Getting thermostat component ready for release

This commit is contained in:
Paulus Schoutsen 2015-01-11 21:21:18 -08:00
parent cac1f56b2d
commit aea6042fe1
8 changed files with 121 additions and 89 deletions

View file

@ -10,12 +10,14 @@ import homeassistant as ha
import homeassistant.loader as loader import homeassistant.loader as loader
from homeassistant.helpers import extract_entity_ids from homeassistant.helpers import extract_entity_ids
from homeassistant.const import ( from homeassistant.const import (
SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_ON, STATE_OFF, SERVICE_TURN_ON, SERVICE_TURN_OFF,
ATTR_ENTITY_PICTURE, ATTR_ENTITY_ID, CONF_LATITUDE, CONF_LONGITUDE) STATE_ON, STATE_OFF, TEMP_CELCIUS,
ATTR_ENTITY_PICTURE, ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT,
CONF_LATITUDE, CONF_LONGITUDE)
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_XY_COLOR, ATTR_RGB_COLOR, ATTR_BRIGHTNESS, GROUP_NAME_ALL_LIGHTS) ATTR_XY_COLOR, ATTR_RGB_COLOR, ATTR_BRIGHTNESS, GROUP_NAME_ALL_LIGHTS)
from homeassistant.components.thermostat import ( from homeassistant.components.thermostat import (
ATTR_TARGET_TEMPERATURE, ATTR_AWAY_MODE) ATTR_CURRENT_TEMPERATURE, ATTR_AWAY_MODE)
from homeassistant.util import split_entity_id, color_RGB_to_xy from homeassistant.util import split_entity_id, color_RGB_to_xy
DOMAIN = "demo" DOMAIN = "demo"
@ -161,10 +163,10 @@ def setup(hass, config):
}) })
# Nest demo # Nest demo
hass.states.set("thermostat.Nest", "15.6", hass.states.set("thermostat.Nest", "23",
{ {
'unit_of_measurement': '°C', ATTR_UNIT_OF_MEASUREMENT: TEMP_CELCIUS,
ATTR_TARGET_TEMPERATURE: '23.6', ATTR_CURRENT_TEMPERATURE: '18',
ATTR_AWAY_MODE: STATE_OFF ATTR_AWAY_MODE: STATE_OFF
}) })

View file

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """ """ DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "7dec66ac57c858565b26db16e150a3b5" VERSION = "7484b7aecbe15593d924b47daf4a89df"

File diff suppressed because one or more lines are too long

View file

@ -8,28 +8,30 @@
<style> <style>
.state { .state {
margin-left: 16px; margin-left: 16px;
text-transform: capitalize;
font-weight: 300;
font-size: 1.3rem;
text-align: right; text-align: right;
} }
.extra { .target {
text-transform: none; text-transform: capitalize;
font-size: 1rem; font-weight: 300;
font-size: 1.3rem;
}
.current {
color: darkgrey;
margin-top: -2px;
} }
</style> </style>
<div horizontal justified layout> <div horizontal justified layout>
<state-info stateObj="{{stateObj}}"></state-info> <state-info stateObj="{{stateObj}}"></state-info>
<div class='state'> <div class='state'>
{{stateObj.stateDisplay}} <div class='target'>
<template if="{{stateObj.attributes.target_temperature && stateObj.attributes.target_temperature != stateObj.state}}"> {{stateObj.stateDisplay}}
-> {{stateObj.attributes.target_temperature}} {{stateObj.attributes.unit_of_measurement}} </div>
</template>
<div class='extra'> <div class='current'>
Away mode is {{stateObj.attributes.away_mode}} Currently: {{stateObj.attributes.current_temperature}} {{stateObj.attributes.unit_of_measurement}}
</div> </div>
</div> </div>
</div> </div>

View file

@ -57,10 +57,7 @@
return "announcement"; return "announcement";
case "thermostat": case "thermostat":
return "homeassistant:nest-thermostat"; return "homeassistant:thermostat";
case "smokedetector":
return "homeassistant:nest-protect";
default: default:
return "bookmark-outline"; return "bookmark-outline";

View file

@ -1,14 +1,13 @@
<link rel="import" href="../bower_components/core-icon/core-icon.html"> <link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/core-iconset-svg/core-iconset-svg.html"> <link rel="import" href="../bower_components/core-iconset-svg/core-iconset-svg.html">
<core-iconset-svg id="homeassistant" iconSize="24"> <core-iconset-svg id="homeassistant" iconSize="100">
<svg><defs> <svg><defs>
<g id="thermostat">
<!-- <!--
The following two icons are Copyright (c) 2014 The Polymer Project Authors. Thermostat icon created by Scott Lewis from the Noun Project
This code may only be used under the BSD style license found at Licensed under CC BY 3.0 - http://creativecommons.org/licenses/by/3.0/us/
http://polymer.github.io/LICENSE.txt
--> -->
<g id="nest-thermostat"><path d="M12,2C6.5,2,2,6.5,2,12c0,5.5,4.5,10,10,10c5.5,0,10-4.5,10-10C22,6.5,17.5,2,12,2z M12,5c1.6,0,3,0.5,4.2,1.4L14,8.6C13.4,8.2,12.7,8,12,8c-2.2,0-4,1.8-4,4c0,1.1,0.4,2.1,1.2,2.8l-2.1,2.1C5.8,15.7,5,13.9,5,12C5,8.1,8.1,5,12,5z M16.9,16.9l-2.1-2.1c0.7-0.7,1.2-1.7,1.2-2.8c0-0.7-0.2-1.4-0.6-2l2.2-2.2C18.5,9,19,10.4,19,12C19,13.9,18.2,15.7,16.9,16.9z"/></g> <path d="M66.861,60.105V17.453c0-9.06-7.347-16.405-16.408-16.405c-9.06,0-16.404,7.345-16.404,16.405v42.711 c-4.04,4.14-6.533,9.795-6.533,16.035c0,12.684,10.283,22.967,22.967,22.967c12.682,0,22.964-10.283,22.964-22.967 C73.447,69.933,70.933,64.254,66.861,60.105z M60.331,20.38h-13.21v6.536h6.63v6.539h-6.63v6.713h6.63v6.538h-6.63v6.5h6.63v6.536 h-6.63v7.218c-3.775,1.373-6.471,4.993-6.471,9.24h-6.626c0-5.396,2.598-10.182,6.61-13.185V17.446c0-0.038,0.004-0.075,0.004-0.111 l-0.004-0.007c0-5.437,4.411-9.846,9.849-9.846c5.438,0,9.848,4.409,9.848,9.846V20.38z"/></g>
<g id="nest-protect"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6c3.3,0,6,2.7,6,6S15.3,18,12,18z"/><circle cx="12" cy="12" r="4"/></g>
</defs></svg> </defs></svg>
</core-iconset-svg> </core-iconset-svg>

View file

@ -26,7 +26,7 @@ SERVICE_TURN_AWAY_MODE_ON = "turn_away_mode_on"
SERVICE_TURN_AWAY_MODE_OFF = "turn_away_mode_off" SERVICE_TURN_AWAY_MODE_OFF = "turn_away_mode_off"
SERVICE_SET_TEMPERATURE = "set_temperature" SERVICE_SET_TEMPERATURE = "set_temperature"
ATTR_TARGET_TEMPERATURE = "target_temperature" ATTR_CURRENT_TEMPERATURE = "current_temperature"
ATTR_AWAY_MODE = "away_mode" ATTR_AWAY_MODE = "away_mode"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -59,6 +59,8 @@ def set_temperature(hass, temperature, entity_id=None):
def setup(hass, config): def setup(hass, config):
""" Setup thermostats. """ """ Setup thermostats. """
logger = logging.getLogger(__name__)
thermostats = platform_devices_from_config( thermostats = platform_devices_from_config(
config, DOMAIN, hass, ENTITY_ID_FORMAT, _LOGGER) config, DOMAIN, hass, ENTITY_ID_FORMAT, _LOGGER)
@ -69,7 +71,7 @@ def setup(hass, config):
@util.Throttle(MIN_TIME_BETWEEN_SCANS) @util.Throttle(MIN_TIME_BETWEEN_SCANS)
def update_state(now): def update_state(now):
""" Update thermostat state. """ """ Update thermostat state. """
logging.getLogger(__name__).info("Update nest state") logger.info("Updating nest state")
for thermostat in thermostats.values(): for thermostat in thermostats.values():
thermostat.update_ha_state(hass, True) thermostat.update_ha_state(hass, True)
@ -126,6 +128,59 @@ class ThermostatDevice(Device):
# pylint: disable=no-self-use # pylint: disable=no-self-use
@property
def state(self):
""" Returns the current state. """
return self.target_temperature
@property
def unit_of_measurement(self):
""" Returns the unit of measurement. """
return ""
@property
def device_state_attributes(self):
""" Returns device specific state attributes. """
return None
@property
def state_attributes(self):
""" Returns optional state attributes. """
data = {
ATTR_UNIT_OF_MEASUREMENT: self.unit_of_measurement,
ATTR_CURRENT_TEMPERATURE: self.current_temperature
}
is_away = self.is_away_mode_on
if is_away is not None:
data[ATTR_AWAY_MODE] = STATE_ON if is_away else STATE_OFF
device_attr = self.device_state_attributes
if device_attr is not None:
data.update(device_attr)
return data
@property
def current_temperature(self):
""" Returns the current temperature. """
raise NotImplementedError
@property
def target_temperature(self):
""" Returns the temperature we try to reach. """
raise NotImplementedError
@property
def is_away_mode_on(self):
"""
Returns if away mode is on.
Return None if no away mode available.
"""
return None
def set_temperate(self, temperature): def set_temperate(self, temperature):
""" Set new target temperature. """ """ Set new target temperature. """
pass pass
@ -137,33 +192,3 @@ class ThermostatDevice(Device):
def turn_away_mode_off(self): def turn_away_mode_off(self):
""" Turns away mode off. """ """ Turns away mode off. """
pass pass
def is_away_mode_on(self):
""" Returns if away mode is on. """
return False
def get_target_temperature(self):
""" Returns the temperature we try to reach. """
return None
def get_unit_of_measurement(self):
""" Returns the unit of measurement. """
return ""
def get_device_state_attributes(self):
""" Returns device specific state attributes. """
return {}
def get_state_attributes(self):
""" Returns optional state attributes. """
data = {
ATTR_UNIT_OF_MEASUREMENT: self.get_unit_of_measurement(),
ATTR_AWAY_MODE: STATE_ON if self.is_away_mode_on() else STATE_OFF
}
target_temp = self.get_target_temperature()
if target_temp is not None:
data[ATTR_TARGET_TEMPERATURE] = target_temp
return data

View file

@ -29,9 +29,7 @@ def get_devices(hass, config):
return [] return []
thermostat = NestThermostat(username, password) return [NestThermostat(username, password)]
return [thermostat]
class NestThermostat(ThermostatDevice): class NestThermostat(ThermostatDevice):
@ -41,17 +39,40 @@ class NestThermostat(ThermostatDevice):
# pylint: disable=no-name-in-module, import-error # pylint: disable=no-name-in-module, import-error
import homeassistant.external.pynest.nest as pynest import homeassistant.external.pynest.nest as pynest
self.nest = pynest.Nest(username, password, None) self.nest = pynest.Nest(username, password)
self.nest.login() self.nest.login()
self.update()
def get_name(self): @property
def name(self):
""" Returns the name of the nest, if any. """ """ Returns the name of the nest, if any. """
return "Nest" # TODO Possible to get actual name from Nest device? return "Nest" # TODO Possible to get actual name from Nest device?
def get_state(self): @property
def unit_of_measurement(self):
""" Returns the unit of measurement. """
return TEMP_FAHRENHEIT if self.nest.units == 'F' else TEMP_CELCIUS
@property
def device_state_attributes(self):
""" Returns device specific state attributes. """
return None
@property
def current_temperature(self):
""" Returns the current temperature. """ """ Returns the current temperature. """
return self.nest.get_curtemp() return self.nest.get_curtemp()
@property
def target_temperature(self):
""" Returns the temperature we try to reach. """
return self.nest.get_tartemp()
@property
def is_away_mode_on(self):
""" Returns if away mode is on. """
return self.nest.is_away()
def set_temperature(self, temperature): def set_temperature(self, temperature):
""" Set new target temperature """ """ Set new target temperature """
self.nest.set_temperature(temperature) self.nest.set_temperature(temperature)
@ -64,18 +85,6 @@ class NestThermostat(ThermostatDevice):
""" Turns away off. """ """ Turns away off. """
self.nest.set_away("here") self.nest.set_away("here")
def is_away_mode_on(self): def update(self):
""" Returns if away mode is on. """ """ Update nest. """
return self.nest.is_away() self.nest.get_status()
def get_target_temperature(self):
""" Returns the temperature we try to reach. """
return self.nest.get_tartemp()
def get_unit_of_measurement(self):
""" Returns the unit of measurement. """
return TEMP_FAHRENHEIT if self.nest.units == 'F' else TEMP_CELCIUS
def get_device_state_attributes(self):
""" Returns device specific state attributes. """
return {}