mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
Add Z-Wave thermostat
based on @coteyr work and with a help from @turbokongen
This commit is contained in:
parent
c7fd0eb9d9
commit
4fba89b789
@ -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'
|
||||
}
|
||||
|
||||
|
||||
|
114
homeassistant/components/thermostat/zwave.py
Normal file
114
homeassistant/components/thermostat/zwave.py
Normal 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
|
@ -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),
|
||||
]
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user