mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 14:57:09 +00:00
fixed sensors and thermostat. discovery working for both now.
This commit is contained in:
parent
8dc0de1d05
commit
cc196d9888
@ -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. """
|
||||||
|
@ -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'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.")
|
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user