Merge branch 'pr/635' into dev

Conflicts:
	requirements_all.txt
This commit is contained in:
Paulus Schoutsen 2015-11-28 00:50:18 -08:00
commit bbfeba0fe4
8 changed files with 475 additions and 3 deletions

View File

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

View File

@ -0,0 +1,154 @@
"""
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 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)
from datetime import timedelta
import logging
import os
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/'
'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, 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -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'
SCAN_INTERVAL = 30
@ -21,7 +21,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'
}

View File

@ -0,0 +1,94 @@
"""
homeassistant.components.sensor.ecobee
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
"""
from homeassistant.helpers.entity import Entity
from homeassistant.components import ecobee
from homeassistant.const import TEMP_FAHRENHEIT
import logging
DEPENDENCIES = ['ecobee']
SENSOR_TYPES = {
'temperature': ['Temperature', TEMP_FAHRENHEIT],
'humidity': ['Humidity', '%'],
'occupancy': ['Occupancy', '']
}
_LOGGER = logging.getLogger(__name__)
ECOBEE_CONFIG_FILE = 'ecobee.conf'
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Sets up the sensors. """
if discovery_info is None:
return
dev = list()
for name, data in ecobee.NETWORK.ecobee.sensors.items():
if 'temp' in data:
dev.append(EcobeeSensor(name, 'temperature'))
if 'humidity' in data:
dev.append(EcobeeSensor(name, 'humidity'))
if 'occupancy' in data:
dev.append(EcobeeSensor(name, 'occupancy'))
add_devices(dev)
class EcobeeSensor(Entity):
""" An ecobee sensor. """
def __init__(self, sensor_name, sensor_type):
self._name = sensor_name + ' ' + SENSOR_TYPES[sensor_type][0]
self.sensor_name = sensor_name
self.type = sensor_type
self._state = None
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
self.update()
@property
def name(self):
return self._name.rstrip()
@property
def state(self):
""" Returns the state of the device. """
return self._state
@property
def unit_of_measurement(self):
return self._unit_of_measurement
def update(self):
ecobee.NETWORK.update()
data = ecobee.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']

View File

@ -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)
@ -41,6 +42,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. """
@ -66,7 +71,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):

View File

@ -0,0 +1,209 @@
"""
homeassistant.components.thermostat.ecobee
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
"""
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 import ecobee
import logging
DEPENDENCIES = ['ecobee']
_LOGGER = logging.getLogger(__name__)
ECOBEE_CONFIG_FILE = 'ecobee.conf'
_CONFIGURING = {}
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Setup Platform """
if discovery_info is None:
return
data = ecobee.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, 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)
@property
def name(self):
""" Returns the name of the Ecobee Thermostat. """
return self.thermostat['name']
@property
def unit_of_measurement(self):
""" Unit of measurement this thermostat expresses itself in. """
return TEMP_FAHRENHEIT
@property
def current_temperature(self):
""" Returns the current temperature. """
return self.thermostat['runtime']['actualTemperature'] / 10
@property
def target_temperature(self):
""" Returns the temperature we try to reach. """
return (self.target_temperature_low + self.target_temperature_high) / 2
@property
def target_temperature_low(self):
""" Returns the lower bound temperature we try to reach. """
return int(self.thermostat['runtime']['desiredHeat'] / 10)
@property
def target_temperature_high(self):
""" Returns the upper bound temperature we try to reach. """
return int(self.thermostat['runtime']['desiredCool'] / 10)
@property
def humidity(self):
""" Returns the current humidity. """
return self.thermostat['runtime']['actualHumidity']
@property
def desired_fan_mode(self):
""" Returns the desired fan mode of operation. """
return self.thermostat['runtime']['desiredFanMode']
@property
def fan(self):
""" Returns the current fan state. """
if 'fan' in self.thermostat['equipmentStatus']:
return STATE_ON
else:
return STATE_OFF
@property
def operation(self):
""" Returns current operation ie. heat, cool, idle """
status = self.thermostat['equipmentStatus']
if status == '':
return STATE_IDLE
elif 'Cool' in status:
return STATE_COOL
elif 'auxHeat' in status:
return STATE_HEAT
elif 'heatPump' in status:
return STATE_HEAT
else:
return status
@property
def mode(self):
""" Returns current mode ie. home, away, sleep """
mode = self.thermostat['program']['currentClimateRef']
self._away = 'away' in mode
return mode
@property
def hvac_mode(self):
""" Return current hvac mode ie. auto, auxHeatOnly, cool, heat, off """
return self.thermostat['settings']['hvacMode']
@property
def device_state_attributes(self):
""" Returns device specific state attributes. """
# Move these to Thermostat Device and make them global
return {
"humidity": self.humidity,
"fan": self.fan,
"mode": self.mode,
"hvac_mode": self.hvac_mode
}
@property
def is_away_mode_on(self):
""" Returns if away mode is on. """
return self._away
def turn_away_mode_on(self):
""" Turns away on. """
self._away = True
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. """
self._away = False
self.data.ecobee.resume_program()
def set_temperature(self, temperature):
""" Set new target temperature """
temperature = int(temperature)
low_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)
def set_hvac_mode(self, mode):
""" Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """
self.data.ecobee.set_hvac_mode(mode)
# Home and Sleep mode aren't used in UI yet:
# def turn_home_mode_on(self):
# """ Turns home mode on. """
# self._away = False
# self.data.ecobee.set_climate_hold("home")
# def turn_home_mode_off(self):
# """ Turns home mode off. """
# self._away = False
# self.data.ecobee.resume_program()
# def turn_sleep_mode_on(self):
# """ Turns sleep mode on. """
# self._away = False
# self.data.ecobee.set_climate_hold("sleep")
# def turn_sleep_mode_off(self):
# """ Turns sleep mode off. """
# self._away = False
# self.data.ecobee.resume_program()

View File

@ -20,6 +20,9 @@ pysnmp==4.2.5
# homeassistant.components.discovery
netdisco==0.5.1
# homeassistant.components.ecobee
https://github.com/nkgilley/python-ecobee-api/archive/d35596b67c75451fa47001c493a15eebee195e93.zip#python-ecobee==0.0.1
# homeassistant.components.ifttt
pyfttt==0.3
@ -75,6 +78,8 @@ https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b6
# homeassistant.components.mqtt
paho-mqtt==1.1
# homeassistant.components.mqtt
jsonpath-rw==1.4.0
# homeassistant.components.notify.pushbullet