From cc196d988867fe7e7d08c062c3ca06bf3383bdcf Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Mon, 23 Nov 2015 11:15:19 -0500 Subject: [PATCH] fixed sensors and thermostat. discovery working for both now. --- homeassistant/components/ecobee.py | 70 ++++++++++++------ homeassistant/components/sensor/__init__.py | 5 +- homeassistant/components/sensor/ecobee.py | 73 ++++++++++--------- .../components/thermostat/__init__.py | 8 +- homeassistant/components/thermostat/ecobee.py | 35 ++++++--- 5 files changed, 118 insertions(+), 73 deletions(-) diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py index ef982a15e63..8b73a9969ef 100644 --- a/homeassistant/components/ecobee.py +++ b/homeassistant/components/ecobee.py @@ -1,13 +1,29 @@ """ homeassistant.components.ecobee -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -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 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 -[ecobee] -api_key: asdflaksf """ from homeassistant.loader import get_component @@ -22,8 +38,10 @@ import os DOMAIN = "ecobee" DISCOVER_THERMOSTAT = "ecobee.thermostat" +DISCOVER_SENSORS = "ecobee.sensor" DEPENDENCIES = [] NETWORK = None +HOLD_TEMP = 'hold_temp' REQUIREMENTS = [ 'https://github.com/nkgilley/python-ecobee-api/archive/' @@ -38,7 +56,7 @@ _CONFIGURING = {} MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) -def request_configuration(network, hass): +def request_configuration(network, hass, config): """ Request configuration steps from the user. """ configurator = get_component('configurator') if 'ecobee' in _CONFIGURING: @@ -52,7 +70,7 @@ def request_configuration(network, hass): """ Actions to do when our configuration callback is called. """ network.request_tokens() network.update() - setup_ecobee(hass, network) + setup_ecobee(hass, network, config) _CONFIGURING['ecobee'] = configurator.request_config( hass, "Ecobee", ecobee_configuration_callback, @@ -64,17 +82,35 @@ def request_configuration(network, hass): ) -def setup_ecobee(hass, network): +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) + 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') + bootstrap.setup_component(hass, 'sensor') + + 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): @@ -88,6 +124,7 @@ class EcobeeData(object): def update(self): """ Get the latest data from pyecobee. """ self.ecobee.update() + _LOGGER.info("ecobee data updated successfully.") def setup(hass, config): @@ -114,18 +151,7 @@ def setup(hass, config): NETWORK = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) - setup_ecobee(hass, NETWORK.ecobee) - - # 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, - } - }) + setup_ecobee(hass, NETWORK.ecobee, config) def stop_ecobee(event): """ Stop Ecobee. """ diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 32ee59a6fa9..0d214475358 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -9,7 +9,7 @@ https://home-assistant.io/components/sensor/ import logging from homeassistant.helpers.entity_component import EntityComponent -from homeassistant.components import wink, zwave, isy994, verisure +from homeassistant.components import wink, zwave, isy994, verisure, ecobee DOMAIN = 'sensor' DEPENDENCIES = [] @@ -22,7 +22,8 @@ DISCOVERY_PLATFORMS = { wink.DISCOVER_SENSORS: 'wink', zwave.DISCOVER_SENSORS: 'zwave', isy994.DISCOVER_SENSORS: 'isy994', - verisure.DISCOVER_SENSORS: 'verisure' + verisure.DISCOVER_SENSORS: 'verisure', + ecobee.DISCOVER_SENSORS: 'ecobee' } diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py index a8d9e41acb1..b7663a70d6a 100644 --- a/homeassistant/components/sensor/ecobee.py +++ b/homeassistant/components/sensor/ecobee.py @@ -1,22 +1,39 @@ """ homeassistant.components.sensor.ecobee -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This sensor component requires that the Ecobee Thermostat -component be setup first. This component shows remote -ecobee sensor data. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ecobee Thermostat 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 -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/sensor.ecobee/ """ from homeassistant.helpers.entity import Entity -import json +from homeassistant.components.ecobee import NETWORK +from homeassistant.const import TEMP_FAHRENHEIT import logging -import os -DEPENDENCIES = ['thermostat'] +DEPENDENCIES = ['ecobee'] SENSOR_TYPES = { - 'temperature': ['Temperature', '°F'], + 'temperature': ['Temperature', TEMP_FAHRENHEIT], 'humidity': ['Humidity', '%'], 'occupancy': ['Occupancy', ''] } @@ -26,24 +43,12 @@ _LOGGER = logging.getLogger(__name__) ECOBEE_CONFIG_FILE = 'ecobee.conf' -def config_from_file(filename): - ''' Small configuration file reading function ''' - if os.path.isfile(filename): - try: - with open(filename, 'r') as fdesc: - return json.loads(fdesc.read()) - except IOError as error: - _LOGGER.error("ecobee sensor couldn't read config file: " + error) - return False - else: - return {} - - def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the sensors. """ - config = config_from_file(hass.config.path(ECOBEE_CONFIG_FILE)) + if discovery_info is None: + return dev = list() - for name, data in config['sensors'].items(): + for name, data in NETWORK.ecobee.sensors.items(): if 'temp' in data: dev.append(EcobeeSensor(name, 'temperature', hass)) if 'humidity' in data: @@ -80,14 +85,10 @@ class EcobeeSensor(Entity): return self._unit_of_measurement def update(self): - config = config_from_file(self.hass.config.path(ECOBEE_CONFIG_FILE)) - try: - data = config['sensors'][self.sensor_name] - if self.type == 'temperature': - self._state = data['temp'] - elif self.type == 'humidity': - self._state = data['humidity'] - elif self.type == 'occupancy': - self._state = data['occupancy'] - except KeyError: - print("Error updating ecobee sensors.") + data = NETWORK.ecobee.sensors[self.sensor_name] + if self.type == 'temperature': + self._state = data['temp'] + elif self.type == 'humidity': + self._state = data['humidity'] + elif self.type == 'occupancy': + self._state = data['occupancy'] diff --git a/homeassistant/components/thermostat/__init__.py b/homeassistant/components/thermostat/__init__.py index 480e3e4805e..f1a82a4c989 100644 --- a/homeassistant/components/thermostat/__init__.py +++ b/homeassistant/components/thermostat/__init__.py @@ -15,6 +15,7 @@ from homeassistant.config import load_yaml_config_file import homeassistant.util as util from homeassistant.helpers.entity import Entity from homeassistant.helpers.temperature import convert +from homeassistant.components import ecobee from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN, TEMP_CELCIUS) @@ -42,6 +43,10 @@ ATTR_OPERATION = "current_operation" _LOGGER = logging.getLogger(__name__) +DISCOVERY_PLATFORMS = { + ecobee.DISCOVER_THERMOSTAT: 'ecobee', +} + def set_away_mode(hass, away_mode, entity_id=None): """ Turn all or specified thermostat away mode on. """ @@ -67,7 +72,8 @@ def set_temperature(hass, temperature, entity_id=None): def setup(hass, config): """ Setup thermostats. """ - component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL) + component = EntityComponent(_LOGGER, DOMAIN, hass, + SCAN_INTERVAL, DISCOVERY_PLATFORMS) component.setup(config) def thermostat_service(service): diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 7f95aa7d1c6..51d21cb9991 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -15,17 +15,20 @@ 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 should shown in home-assistant. Once the -thermostat has been added you can add the ecobee sensor component -to your configuration.yaml. +card. Now your thermostat and sensors should shown in home-assistant. -thermostat: - platform: ecobee +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 homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) +from homeassistant.components.ecobee import NETWORK import logging DEPENDENCIES = ['ecobee'] @@ -38,30 +41,32 @@ _CONFIGURING = {} def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup Platform """ - _LOGGER.error("ecobee !!!!") if discovery_info is None: return - data = discovery_info[0] - add_devices(Thermostat(data, index) + data = NETWORK + hold_temp = discovery_info['hold_temp'] + _LOGGER.info("Loading ecobee thermostat component with hold_temp set to " + + str(hold_temp)) + add_devices(Thermostat(data, index, hold_temp) for index in range(len(data.ecobee.thermostats))) class Thermostat(ThermostatDevice): """ Thermostat class for Ecobee """ - def __init__(self, data, thermostat_index): + def __init__(self, data, thermostat_index, hold_temp): self.data = data self.thermostat_index = thermostat_index self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) self._name = self.thermostat['name'] self._away = 'away' in self.thermostat['program']['currentClimateRef'] + self.hold_temp = hold_temp def update(self): self.data.update() self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) - _LOGGER.info("ecobee data updated successfully.") @property def name(self): @@ -157,7 +162,10 @@ class Thermostat(ThermostatDevice): def turn_away_mode_on(self): """ Turns away on. """ self._away = True - self.data.ecobee.set_climate_hold("away") + if self.hold_temp: + self.data.ecobee.set_climate_hold("away", "indefinite") + else: + self.data.ecobee.set_climate_hold("away") def turn_away_mode_off(self): """ Turns away off. """ @@ -169,7 +177,10 @@ class Thermostat(ThermostatDevice): temperature = int(temperature) low_temp = temperature - 1 high_temp = temperature + 1 - self.data.ecobee.set_hold_temp(low_temp, high_temp) + if self.hold_temp: + self.data.ecobee.set_hold_temp(low_temp, high_temp, "indefinite") + else: + self.data.ecobee.set_hold_temp(low_temp, high_temp) def set_hvac_mode(self, mode): """ Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """