use Throttle like the BitCoin component.

This commit is contained in:
nkgilley@gmail.com 2015-11-18 14:57:27 -05:00
parent 8df32aac3c
commit d05af62680
2 changed files with 50 additions and 33 deletions

View File

@ -16,6 +16,7 @@ omit =
homeassistant/components/*/tellstick.py homeassistant/components/*/tellstick.py
homeassistant/components/*/vera.py homeassistant/components/*/vera.py
homeassistant/components/*/ecobee.py
homeassistant/components/verisure.py homeassistant/components/verisure.py
homeassistant/components/*/verisure.py homeassistant/components/*/verisure.py

View File

@ -29,18 +29,23 @@ from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL,
STATE_IDLE, STATE_HEAT) STATE_IDLE, STATE_HEAT)
from homeassistant.const import ( from homeassistant.const import (
CONF_API_KEY, TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) CONF_API_KEY, TEMP_FAHRENHEIT, STATE_ON, STATE_OFF)
from homeassistant.util import Throttle
from datetime import timedelta
import logging import logging
import os import os
REQUIREMENTS = [ REQUIREMENTS = [
'https://github.com/nkgilley/python-ecobee-api/archive/' 'https://github.com/nkgilley/python-ecobee-api/archive/'
'730009b9593899d42e98c81a0544f91e65b2bc15.zip#python-ecobee==0.0.1'] '790c20d820dbb727af2dbfb3ef0f79231e19a503.zip#python-ecobee==0.0.1']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ECOBEE_CONFIG_FILE = 'ecobee.conf' ECOBEE_CONFIG_FILE = 'ecobee.conf'
_CONFIGURING = {} _CONFIGURING = {}
# Return cached results if last scan was less then this time ago
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_callback, discovery_info=None):
""" Setup Platform """ """ Setup Platform """
@ -48,33 +53,32 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
if 'ecobee' in _CONFIGURING: if 'ecobee' in _CONFIGURING:
return return
setup_ecobee(hass, config, add_devices_callback) from pyecobee import config_from_file
def setup_ecobee(hass, config, add_devices_callback):
""" Setup ecobee thermostat """
from pyecobee import Ecobee, config_from_file
# Create ecobee.conf if it doesn't exist # Create ecobee.conf if it doesn't exist
if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)):
jsonconfig = {"API_KEY": config[CONF_API_KEY]} jsonconfig = {"API_KEY": config[CONF_API_KEY]}
config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) 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)
ecobee = Ecobee(hass.config.path(ECOBEE_CONFIG_FILE))
def setup_ecobee(hass, data, config, add_devices_callback):
""" 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 ecobee.pin is not None: if data.ecobee.pin is not None:
request_configuration(ecobee, hass, add_devices_callback) request_configuration(data, hass, add_devices_callback)
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'))
add_devices_callback(Thermostat(ecobee, index) add_devices_callback(Thermostat(data, index)
for index in range(len(ecobee.thermostats))) for index in range(len(data.ecobee.thermostats)))
def request_configuration(ecobee, hass, add_devices_callback): def request_configuration(data, hass, add_devices_callback):
""" 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:
@ -84,35 +88,50 @@ def request_configuration(ecobee, hass, add_devices_callback):
return return
# pylint: disable=unused-argument # pylint: disable=unused-argument
def ecobee_configuration_callback(data): def ecobee_configuration_callback(callback_data):
""" Actions to do when our configuration callback is called. """ """ Actions to do when our configuration callback is called. """
ecobee.request_tokens() data.ecobee.request_tokens()
ecobee.update() data.ecobee.update()
setup_ecobee(hass, None, add_devices_callback) setup_ecobee(hass, data, None, add_devices_callback)
_CONFIGURING['ecobee'] = configurator.request_config( _CONFIGURING['ecobee'] = configurator.request_config(
hass, "Ecobee", ecobee_configuration_callback, hass, "Ecobee", ecobee_configuration_callback,
description=( description=(
'Please authorize this app at https://www.ecobee.com/consumer' 'Please authorize this app at https://www.ecobee.com/consumer'
'portal/index.html with pin code: ' + ecobee.pin), 'portal/index.html with pin code: ' + data.ecobee.pin),
description_image="/static/images/config_ecobee_thermostat.png", description_image="/static/images/config_ecobee_thermostat.png",
submit_caption="I have authorized the app." submit_caption="I have authorized the app."
) )
# 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)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
""" Get the latest data from pyecobee. """
self.ecobee.update()
class Thermostat(ThermostatDevice): class Thermostat(ThermostatDevice):
""" Thermostat class for Ecobee """ """ Thermostat class for Ecobee """
def __init__(self, ecobee, thermostat_index): def __init__(self, data, thermostat_index):
self.ecobee = ecobee self.data = data
self.thermostat_index = thermostat_index self.thermostat_index = thermostat_index
self.thermostat = self.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']
def update(self): def update(self):
self.thermostat = self.ecobee.get_thermostat( self.data.update()
self.thermostat = self.data.ecobee.get_thermostat(
self.thermostat_index) self.thermostat_index)
_LOGGER.info("ecobee data updated successfully.") _LOGGER.info("ecobee data updated successfully.")
@ -183,10 +202,7 @@ class Thermostat(ThermostatDevice):
def mode(self): def mode(self):
""" Returns current mode ie. home, away, sleep """ """ Returns current mode ie. home, away, sleep """
mode = self.thermostat['program']['currentClimateRef'] mode = self.thermostat['program']['currentClimateRef']
if 'away' in mode: self._away = 'away' in mode
self._away = True
else:
self._away = False
return mode return mode
@property @property
@ -213,42 +229,42 @@ 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
self.ecobee.set_climate_hold("away") self.data.ecobee.set_climate_hold("away")
def turn_away_mode_off(self): def turn_away_mode_off(self):
""" Turns away off. """ """ Turns away off. """
self._away = False self._away = False
self.ecobee.resume_program() self.data.ecobee.resume_program()
def set_temperature(self, temperature): def set_temperature(self, temperature):
""" Set new target temperature """ """ Set new target temperature """
temperature = int(temperature) temperature = int(temperature)
low_temp = temperature - 1 low_temp = temperature - 1
high_temp = temperature + 1 high_temp = temperature + 1
self.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):
""" Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """ """ Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """
self.ecobee.set_hvac_mode(mode) self.data.ecobee.set_hvac_mode(mode)
# Home and Sleep mode aren't used in UI yet: # Home and Sleep mode aren't used in UI yet:
# def turn_home_mode_on(self): # def turn_home_mode_on(self):
# """ Turns home mode on. """ # """ Turns home mode on. """
# self._away = False # self._away = False
# self.ecobee.set_climate_hold("home") # self.data.ecobee.set_climate_hold("home")
# def turn_home_mode_off(self): # def turn_home_mode_off(self):
# """ Turns home mode off. """ # """ Turns home mode off. """
# self._away = False # self._away = False
# self.ecobee.resume_program() # self.data.ecobee.resume_program()
# def turn_sleep_mode_on(self): # def turn_sleep_mode_on(self):
# """ Turns sleep mode on. """ # """ Turns sleep mode on. """
# self._away = False # self._away = False
# self.ecobee.set_climate_hold("sleep") # self.data.ecobee.set_climate_hold("sleep")
# def turn_sleep_mode_off(self): # def turn_sleep_mode_off(self):
# """ Turns sleep mode off. """ # """ Turns sleep mode off. """
# self._away = False # self._away = False
# self.ecobee.resume_program() # self.data.ecobee.resume_program()