Add Z-Wave thermostat

based on @coteyr work and with a help from @turbokongen
This commit is contained in:
Kai 2016-04-03 05:01:03 +02:00 committed by Paulus Schoutsen
parent c7fd0eb9d9
commit 4fba89b789
3 changed files with 124 additions and 2 deletions

View File

@ -14,7 +14,7 @@ import homeassistant.util as util
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.components import ecobee
from homeassistant.components import (ecobee, zwave)
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
TEMP_CELCIUS)
@ -45,6 +45,7 @@ _LOGGER = logging.getLogger(__name__)
DISCOVERY_PLATFORMS = {
ecobee.DISCOVER_THERMOSTAT: 'ecobee',
zwave.DISCOVER_THERMOSTATS: 'zwave'
}

View File

@ -0,0 +1,114 @@
"""ZWave Thermostat."""
# Because we do not compile openzwave on CI
# pylint: disable=import-error
from homeassistant.components.thermostat import DOMAIN
from homeassistant.components.thermostat import (
ThermostatDevice,
STATE_IDLE)
from homeassistant.components.zwave import (
ATTR_NODE_ID, ATTR_VALUE_ID, NETWORK,
ZWaveDeviceEntity)
from homeassistant.const import (TEMP_FAHRENHEIT, TEMP_CELCIUS)
CONF_NAME = 'name'
DEFAULT_NAME = 'ZWave Thermostat'
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the ZWave thermostats."""
if discovery_info is None or NETWORK is None:
return
node = NETWORK.nodes[discovery_info[ATTR_NODE_ID]]
value = node.values[discovery_info[ATTR_VALUE_ID]]
value.set_change_verified(False)
add_devices([ZWaveThermostat(value)])
# pylint: disable=too-many-arguments
class ZWaveThermostat(ZWaveDeviceEntity, ThermostatDevice):
"""Represents a HeatControl thermostat."""
def __init__(self, value):
"""Initialize the zwave thermostat."""
from openzwave.network import ZWaveNetwork
from pydispatch import dispatcher
ZWaveDeviceEntity.__init__(self, value, DOMAIN)
self._node = value.node
self._target_temperature = None
self._current_temperature = None
self._current_operation = STATE_IDLE
self._current_operation_state = STATE_IDLE
self._unit = None
self.update_properties()
# register listener
dispatcher.connect(
self.value_changed, ZWaveNetwork.SIGNAL_VALUE_CHANGED)
def value_changed(self, value):
"""Called when a value has changed on the network."""
if self._value.node == value.node:
self.update_properties()
self.update_ha_state()
def update_properties(self):
"""Callback on data change for the registered node/value pair."""
# set point
for _, value in self._node.get_values(class_id=0x43).items():
if int(value.data) != 0:
self._target_temperature = int(value.data)
# Operation
for _, value in self._node.get_values(class_id=0x40).items():
self._current_operation = value.data_as_string
# Current Temp
for _, value in self._node.get_values_for_command_class(0x31).items():
self._current_temperature = int(value.data)
self._unit = value.units
# COMMAND_CLASS_THERMOSTAT_OPERATING_STATE
for _, value in self._node.get_values(class_id=0x42).items():
self._current_operation_state = value.data_as_string
@property
def should_poll(self):
"""No polling on ZWave."""
return False
@property
def is_fan_on(self):
"""Return if the fan is not idle."""
return self._current_operation_state != 'Idle'
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
unit = self._unit
if unit == 'C':
return TEMP_CELCIUS
elif unit == 'F':
return TEMP_FAHRENHEIT
else:
return unit
return self.hass.config.temperature_unit
@property
def current_temperature(self):
"""Return the current temperature."""
return self._current_temperature
@property
def operation(self):
"""Return the operation mode."""
return self._current_operation
@property
def target_temperature(self):
"""Return the temperature we try to reach."""
return self._target_temperature
def set_temperature(self, temperature):
"""Set new target temperature."""
# set point
for _, value in self._node.get_values_for_command_class(0x43).items():
if int(value.data) != 0:
value.data = temperature

View File

@ -41,6 +41,7 @@ DISCOVER_SENSORS = "zwave.sensors"
DISCOVER_SWITCHES = "zwave.switch"
DISCOVER_LIGHTS = "zwave.light"
DISCOVER_BINARY_SENSORS = 'zwave.binary_sensor'
DISCOVER_THERMOSTATS = 'zwave.thermostat'
EVENT_SCENE_ACTIVATED = "zwave.scene_activated"
@ -52,6 +53,7 @@ COMMAND_CLASS_SENSOR_MULTILEVEL = 49
COMMAND_CLASS_METER = 50
COMMAND_CLASS_BATTERY = 128
COMMAND_CLASS_ALARM = 113 # 0x71
COMMAND_CLASS_THERMOSTAT_MODE = 64 # 0x40
GENRE_WHATEVER = None
GENRE_USER = "User"
@ -86,7 +88,12 @@ DISCOVERY_COMPONENTS = [
DISCOVER_BINARY_SENSORS,
[COMMAND_CLASS_SENSOR_BINARY],
TYPE_BOOL,
GENRE_USER)
GENRE_USER),
('thermostat',
DISCOVER_THERMOSTATS,
[COMMAND_CLASS_THERMOSTAT_MODE],
TYPE_WHATEVER,
GENRE_WHATEVER),
]