fixed sensors and thermostat. discovery working for both now.

This commit is contained in:
nkgilley@gmail.com 2015-11-23 11:15:19 -05:00
parent 8dc0de1d05
commit cc196d9888
5 changed files with 118 additions and 73 deletions

View File

@ -1,13 +1,29 @@
""" """
homeassistant.components.ecobee 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 Ecobee Component
https://home-assistant.io/components/ecobee/
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 from homeassistant.loader import get_component
@ -22,8 +38,10 @@ import os
DOMAIN = "ecobee" DOMAIN = "ecobee"
DISCOVER_THERMOSTAT = "ecobee.thermostat" DISCOVER_THERMOSTAT = "ecobee.thermostat"
DISCOVER_SENSORS = "ecobee.sensor"
DEPENDENCIES = [] DEPENDENCIES = []
NETWORK = None NETWORK = None
HOLD_TEMP = 'hold_temp'
REQUIREMENTS = [ REQUIREMENTS = [
'https://github.com/nkgilley/python-ecobee-api/archive/' 'https://github.com/nkgilley/python-ecobee-api/archive/'
@ -38,7 +56,7 @@ _CONFIGURING = {}
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180)
def request_configuration(network, hass): def request_configuration(network, hass, config):
""" Request configuration steps from the user. """ """ Request configuration steps from the user. """
configurator = get_component('configurator') configurator = get_component('configurator')
if 'ecobee' in _CONFIGURING: if 'ecobee' in _CONFIGURING:
@ -52,7 +70,7 @@ def request_configuration(network, hass):
""" Actions to do when our configuration callback is called. """ """ Actions to do when our configuration callback is called. """
network.request_tokens() network.request_tokens()
network.update() network.update()
setup_ecobee(hass, network) setup_ecobee(hass, network, config)
_CONFIGURING['ecobee'] = configurator.request_config( _CONFIGURING['ecobee'] = configurator.request_config(
hass, "Ecobee", ecobee_configuration_callback, 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 """ """ Setup ecobee thermostat """
# If ecobee has a PIN then it needs to be configured. # If ecobee has a PIN then it needs to be configured.
if network.pin is not None: if network.pin is not None:
request_configuration(network, hass) request_configuration(network, hass, config)
return return
if 'ecobee' in _CONFIGURING: if 'ecobee' in _CONFIGURING:
configurator = get_component('configurator') configurator = get_component('configurator')
configurator.request_done(_CONFIGURING.pop('ecobee')) 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 # pylint: disable=too-few-public-methods
class EcobeeData(object): class EcobeeData(object):
@ -88,6 +124,7 @@ class EcobeeData(object):
def update(self): def update(self):
""" Get the latest data from pyecobee. """ """ Get the latest data from pyecobee. """
self.ecobee.update() self.ecobee.update()
_LOGGER.info("ecobee data updated successfully.")
def setup(hass, config): def setup(hass, config):
@ -114,18 +151,7 @@ def setup(hass, config):
NETWORK = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) NETWORK = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE))
setup_ecobee(hass, NETWORK.ecobee) setup_ecobee(hass, NETWORK.ecobee, config)
# 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): def stop_ecobee(event):
""" Stop Ecobee. """ """ Stop Ecobee. """

View File

@ -9,7 +9,7 @@ https://home-assistant.io/components/sensor/
import logging import logging
from homeassistant.helpers.entity_component import EntityComponent 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' DOMAIN = 'sensor'
DEPENDENCIES = [] DEPENDENCIES = []
@ -22,7 +22,8 @@ DISCOVERY_PLATFORMS = {
wink.DISCOVER_SENSORS: 'wink', wink.DISCOVER_SENSORS: 'wink',
zwave.DISCOVER_SENSORS: 'zwave', zwave.DISCOVER_SENSORS: 'zwave',
isy994.DISCOVER_SENSORS: 'isy994', isy994.DISCOVER_SENSORS: 'isy994',
verisure.DISCOVER_SENSORS: 'verisure' verisure.DISCOVER_SENSORS: 'verisure',
ecobee.DISCOVER_SENSORS: 'ecobee'
} }

View File

@ -1,22 +1,39 @@
""" """
homeassistant.components.sensor.ecobee homeassistant.components.sensor.ecobee
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This sensor component requires that the Ecobee Thermostat
component be setup first. This component shows remote Ecobee Thermostat Component
ecobee sensor data.
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 from homeassistant.helpers.entity import Entity
import json from homeassistant.components.ecobee import NETWORK
from homeassistant.const import TEMP_FAHRENHEIT
import logging import logging
import os
DEPENDENCIES = ['thermostat'] DEPENDENCIES = ['ecobee']
SENSOR_TYPES = { SENSOR_TYPES = {
'temperature': ['Temperature', '°F'], 'temperature': ['Temperature', TEMP_FAHRENHEIT],
'humidity': ['Humidity', '%'], 'humidity': ['Humidity', '%'],
'occupancy': ['Occupancy', ''] 'occupancy': ['Occupancy', '']
} }
@ -26,24 +43,12 @@ _LOGGER = logging.getLogger(__name__)
ECOBEE_CONFIG_FILE = 'ecobee.conf' 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): def setup_platform(hass, config, add_devices, discovery_info=None):
""" Sets up the sensors. """ """ Sets up the sensors. """
config = config_from_file(hass.config.path(ECOBEE_CONFIG_FILE)) if discovery_info is None:
return
dev = list() dev = list()
for name, data in config['sensors'].items(): for name, data in NETWORK.ecobee.sensors.items():
if 'temp' in data: if 'temp' in data:
dev.append(EcobeeSensor(name, 'temperature', hass)) dev.append(EcobeeSensor(name, 'temperature', hass))
if 'humidity' in data: if 'humidity' in data:
@ -80,14 +85,10 @@ class EcobeeSensor(Entity):
return self._unit_of_measurement return self._unit_of_measurement
def update(self): def update(self):
config = config_from_file(self.hass.config.path(ECOBEE_CONFIG_FILE)) data = NETWORK.ecobee.sensors[self.sensor_name]
try:
data = config['sensors'][self.sensor_name]
if self.type == 'temperature': if self.type == 'temperature':
self._state = data['temp'] self._state = data['temp']
elif self.type == 'humidity': elif self.type == 'humidity':
self._state = data['humidity'] self._state = data['humidity']
elif self.type == 'occupancy': elif self.type == 'occupancy':
self._state = data['occupancy'] self._state = data['occupancy']
except KeyError:
print("Error updating ecobee sensors.")

View File

@ -15,6 +15,7 @@ from homeassistant.config import load_yaml_config_file
import homeassistant.util as util import homeassistant.util as util
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert from homeassistant.helpers.temperature import convert
from homeassistant.components import ecobee
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN, ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
TEMP_CELCIUS) TEMP_CELCIUS)
@ -42,6 +43,10 @@ ATTR_OPERATION = "current_operation"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DISCOVERY_PLATFORMS = {
ecobee.DISCOVER_THERMOSTAT: 'ecobee',
}
def set_away_mode(hass, away_mode, entity_id=None): def set_away_mode(hass, away_mode, entity_id=None):
""" Turn all or specified thermostat away mode on. """ """ Turn all or specified thermostat away mode on. """
@ -67,7 +72,8 @@ def set_temperature(hass, temperature, entity_id=None):
def setup(hass, config): def setup(hass, config):
""" Setup thermostats. """ """ Setup thermostats. """
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL) component = EntityComponent(_LOGGER, DOMAIN, hass,
SCAN_INTERVAL, DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)
def thermostat_service(service): def thermostat_service(service):

View File

@ -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. Click My Apps, Add application, Enter Pin and click Authorize.
After authorizing the application click the button in the configuration After authorizing the application click the button in the configuration
card. Now your thermostat should shown in home-assistant. Once the card. Now your thermostat and sensors should shown in home-assistant.
thermostat has been added you can add the ecobee sensor component
to your configuration.yaml.
thermostat: You can use the optional hold_temp parameter to set whether or not holds
platform: ecobee are set indefintely or until the next scheduled event.
ecobee:
api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf
hold_temp: True
""" """
from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL,
STATE_IDLE, STATE_HEAT) STATE_IDLE, STATE_HEAT)
from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF)
from homeassistant.components.ecobee import NETWORK
import logging import logging
DEPENDENCIES = ['ecobee'] DEPENDENCIES = ['ecobee']
@ -38,30 +41,32 @@ _CONFIGURING = {}
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
""" Setup Platform """ """ Setup Platform """
_LOGGER.error("ecobee !!!!")
if discovery_info is None: if discovery_info is None:
return return
data = discovery_info[0] data = NETWORK
add_devices(Thermostat(data, index) 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))) for index in range(len(data.ecobee.thermostats)))
class Thermostat(ThermostatDevice): class Thermostat(ThermostatDevice):
""" Thermostat class for Ecobee """ """ Thermostat class for Ecobee """
def __init__(self, data, thermostat_index): def __init__(self, data, thermostat_index, hold_temp):
self.data = data self.data = data
self.thermostat_index = thermostat_index self.thermostat_index = thermostat_index
self.thermostat = self.data.ecobee.get_thermostat( self.thermostat = self.data.ecobee.get_thermostat(
self.thermostat_index) self.thermostat_index)
self._name = self.thermostat['name'] self._name = self.thermostat['name']
self._away = 'away' in self.thermostat['program']['currentClimateRef'] self._away = 'away' in self.thermostat['program']['currentClimateRef']
self.hold_temp = hold_temp
def update(self): def update(self):
self.data.update() self.data.update()
self.thermostat = self.data.ecobee.get_thermostat( self.thermostat = self.data.ecobee.get_thermostat(
self.thermostat_index) self.thermostat_index)
_LOGGER.info("ecobee data updated successfully.")
@property @property
def name(self): def name(self):
@ -157,6 +162,9 @@ class Thermostat(ThermostatDevice):
def turn_away_mode_on(self): def turn_away_mode_on(self):
""" Turns away on. """ """ Turns away on. """
self._away = True self._away = True
if self.hold_temp:
self.data.ecobee.set_climate_hold("away", "indefinite")
else:
self.data.ecobee.set_climate_hold("away") self.data.ecobee.set_climate_hold("away")
def turn_away_mode_off(self): def turn_away_mode_off(self):
@ -169,6 +177,9 @@ class Thermostat(ThermostatDevice):
temperature = int(temperature) temperature = int(temperature)
low_temp = temperature - 1 low_temp = temperature - 1
high_temp = temperature + 1 high_temp = temperature + 1
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) self.data.ecobee.set_hold_temp(low_temp, high_temp)
def set_hvac_mode(self, mode): def set_hvac_mode(self, mode):