136 lines
3.9 KiB
Python
136 lines
3.9 KiB
Python
"""Support for deCONZ climate devices."""
|
|
from pydeconz.sensor import Thermostat
|
|
|
|
from homeassistant.components.climate import ClimateDevice
|
|
from homeassistant.components.climate.const import (
|
|
HVAC_MODE_AUTO,
|
|
HVAC_MODE_HEAT,
|
|
HVAC_MODE_OFF,
|
|
SUPPORT_TARGET_TEMPERATURE,
|
|
)
|
|
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
|
from homeassistant.core import callback
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
|
|
from .const import ATTR_OFFSET, ATTR_VALVE, NEW_SENSOR
|
|
from .deconz_device import DeconzDevice
|
|
from .gateway import get_gateway_from_config_entry
|
|
|
|
SUPPORT_HVAC = [HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF]
|
|
|
|
|
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
"""Old way of setting up deCONZ platforms."""
|
|
|
|
|
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
|
"""Set up the deCONZ climate devices.
|
|
|
|
Thermostats are based on the same device class as sensors in deCONZ.
|
|
"""
|
|
gateway = get_gateway_from_config_entry(hass, config_entry)
|
|
|
|
@callback
|
|
def async_add_climate(sensors, new=True):
|
|
"""Add climate devices from deCONZ."""
|
|
entities = []
|
|
|
|
for sensor in sensors:
|
|
|
|
if (
|
|
new
|
|
and sensor.type in Thermostat.ZHATYPE
|
|
and (
|
|
gateway.option_allow_clip_sensor
|
|
or not sensor.type.startswith("CLIP")
|
|
)
|
|
):
|
|
entities.append(DeconzThermostat(sensor, gateway))
|
|
|
|
async_add_entities(entities, True)
|
|
|
|
gateway.listeners.append(
|
|
async_dispatcher_connect(
|
|
hass, gateway.async_signal_new_device(NEW_SENSOR), async_add_climate
|
|
)
|
|
)
|
|
|
|
async_add_climate(gateway.api.sensors.values())
|
|
|
|
|
|
class DeconzThermostat(DeconzDevice, ClimateDevice):
|
|
"""Representation of a deCONZ thermostat."""
|
|
|
|
@property
|
|
def supported_features(self):
|
|
"""Return the list of supported features."""
|
|
return SUPPORT_TARGET_TEMPERATURE
|
|
|
|
@property
|
|
def hvac_mode(self):
|
|
"""Return hvac operation ie. heat, cool mode.
|
|
|
|
Need to be one of HVAC_MODE_*.
|
|
"""
|
|
if self._device.mode in SUPPORT_HVAC:
|
|
return self._device.mode
|
|
if self._device.state_on:
|
|
return HVAC_MODE_HEAT
|
|
return HVAC_MODE_OFF
|
|
|
|
@property
|
|
def hvac_modes(self):
|
|
"""Return the list of available hvac operation modes.
|
|
|
|
Need to be a subset of HVAC_MODES.
|
|
"""
|
|
return SUPPORT_HVAC
|
|
|
|
@property
|
|
def current_temperature(self):
|
|
"""Return the current temperature."""
|
|
return self._device.temperature
|
|
|
|
@property
|
|
def target_temperature(self):
|
|
"""Return the target temperature."""
|
|
return self._device.heatsetpoint
|
|
|
|
async def async_set_temperature(self, **kwargs):
|
|
"""Set new target temperature."""
|
|
data = {}
|
|
|
|
if ATTR_TEMPERATURE in kwargs:
|
|
data["heatsetpoint"] = kwargs[ATTR_TEMPERATURE] * 100
|
|
|
|
await self._device.async_set_config(data)
|
|
|
|
async def async_set_hvac_mode(self, hvac_mode):
|
|
"""Set new target hvac mode."""
|
|
if hvac_mode == HVAC_MODE_AUTO:
|
|
data = {"mode": "auto"}
|
|
elif hvac_mode == HVAC_MODE_HEAT:
|
|
data = {"mode": "heat"}
|
|
elif hvac_mode == HVAC_MODE_OFF:
|
|
data = {"mode": "off"}
|
|
|
|
await self._device.async_set_config(data)
|
|
|
|
@property
|
|
def temperature_unit(self):
|
|
"""Return the unit of measurement."""
|
|
return TEMP_CELSIUS
|
|
|
|
@property
|
|
def device_state_attributes(self):
|
|
"""Return the state attributes of the thermostat."""
|
|
attr = {}
|
|
|
|
if self._device.offset:
|
|
attr[ATTR_OFFSET] = self._device.offset
|
|
|
|
if self._device.valve is not None:
|
|
attr[ATTR_VALVE] = self._device.valve
|
|
|
|
return attr
|