mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 17:57:55 +00:00
Add support for Dyson Hot+Cool Fan as a climate device (#14598)
* Added support for dyson hot+cool fan as climate device * Removed decimal place in kelvin units conversion Minor edits to be consistent with Dyson's internal conversion of temperature from kelvin to celsius. It does not include decimal place to convert between kelvin and celsius. * made changes according to comments * Refactored target temp logics, fixed enum issues * changed name of component to entity * removed temperature conversion for min/max property * changed back to 644 permission * added extra tests for almost-all coverage * changed assert method to avoid lack of certain method in py35 * added test_setup_component * shorten line length * fixed mock spec and added checking of message listener is called * added doc string and debug msg * shorten line length * removed pending target temp
This commit is contained in:
parent
731753b604
commit
b6d3a199ce
176
homeassistant/components/climate/dyson.py
Normal file
176
homeassistant/components/climate/dyson.py
Normal file
@ -0,0 +1,176 @@
|
||||
"""
|
||||
Support for Dyson Pure Hot+Cool link fan.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/climate.dyson/
|
||||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.dyson import DYSON_DEVICES
|
||||
from homeassistant.components.climate import (
|
||||
ClimateDevice, STATE_HEAT, STATE_COOL, STATE_IDLE,
|
||||
SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE)
|
||||
from homeassistant.const import TEMP_CELSIUS, ATTR_TEMPERATURE
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
STATE_DIFFUSE = "Diffuse Mode"
|
||||
STATE_FOCUS = "Focus Mode"
|
||||
FAN_LIST = [STATE_FOCUS, STATE_DIFFUSE]
|
||||
OPERATION_LIST = [STATE_HEAT, STATE_COOL]
|
||||
|
||||
SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE
|
||||
| SUPPORT_OPERATION_MODE)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the Dyson fan components."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
from libpurecoollink.dyson_pure_hotcool_link import DysonPureHotCoolLink
|
||||
# Get Dyson Devices from parent component.
|
||||
add_devices(
|
||||
[DysonPureHotCoolLinkDevice(device)
|
||||
for device in hass.data[DYSON_DEVICES]
|
||||
if isinstance(device, DysonPureHotCoolLink)]
|
||||
)
|
||||
|
||||
|
||||
class DysonPureHotCoolLinkDevice(ClimateDevice):
|
||||
"""Representation of a Dyson climate fan."""
|
||||
|
||||
def __init__(self, device):
|
||||
"""Initialize the fan."""
|
||||
self._device = device
|
||||
self._current_temp = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Call when entity is added to hass."""
|
||||
self.hass.async_add_job(self._device.add_message_listener,
|
||||
self.on_message)
|
||||
|
||||
def on_message(self, message):
|
||||
"""Call when new messages received from the climate."""
|
||||
from libpurecoollink.dyson_pure_state import DysonPureHotCoolState
|
||||
|
||||
if isinstance(message, DysonPureHotCoolState):
|
||||
_LOGGER.debug("Message received for climate device %s : %s",
|
||||
self.name, message)
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
return SUPPORT_FLAGS
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the display name of this climate."""
|
||||
return self._device.name
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
"""Return the unit of measurement."""
|
||||
return TEMP_CELSIUS
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
"""Return the current temperature."""
|
||||
if self._device.environmental_state:
|
||||
temperature_kelvin = self._device.environmental_state.temperature
|
||||
if temperature_kelvin != 0:
|
||||
self._current_temp = float("{0:.1f}".format(
|
||||
temperature_kelvin - 273))
|
||||
return self._current_temp
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the target temperature."""
|
||||
heat_target = int(self._device.state.heat_target) / 10
|
||||
return int(heat_target - 273)
|
||||
|
||||
@property
|
||||
def current_humidity(self):
|
||||
"""Return the current humidity."""
|
||||
if self._device.environmental_state:
|
||||
if self._device.environmental_state.humidity == 0:
|
||||
return None
|
||||
return self._device.environmental_state.humidity
|
||||
return None
|
||||
|
||||
@property
|
||||
def current_operation(self):
|
||||
"""Return current operation ie. heat, cool, idle."""
|
||||
from libpurecoollink.const import HeatMode, HeatState
|
||||
if self._device.state.heat_mode == HeatMode.HEAT_ON.value:
|
||||
if self._device.state.heat_state == HeatState.HEAT_STATE_ON.value:
|
||||
return STATE_HEAT
|
||||
return STATE_IDLE
|
||||
return STATE_COOL
|
||||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""Return the list of available operation modes."""
|
||||
return OPERATION_LIST
|
||||
|
||||
@property
|
||||
def current_fan_mode(self):
|
||||
"""Return the fan setting."""
|
||||
from libpurecoollink.const import FocusMode
|
||||
if self._device.state.focus_mode == FocusMode.FOCUS_ON.value:
|
||||
return STATE_FOCUS
|
||||
return STATE_DIFFUSE
|
||||
|
||||
@property
|
||||
def fan_list(self):
|
||||
"""Return the list of available fan modes."""
|
||||
return FAN_LIST
|
||||
|
||||
def set_temperature(self, **kwargs):
|
||||
"""Set new target temperature."""
|
||||
target_temp = kwargs.get(ATTR_TEMPERATURE)
|
||||
if target_temp is None:
|
||||
return
|
||||
target_temp = int(target_temp)
|
||||
_LOGGER.debug("Set %s temperature %s", self.name, target_temp)
|
||||
# Limit the target temperature into acceptable range.
|
||||
target_temp = min(self.max_temp, target_temp)
|
||||
target_temp = max(self.min_temp, target_temp)
|
||||
from libpurecoollink.const import HeatTarget, HeatMode
|
||||
self._device.set_configuration(
|
||||
heat_target=HeatTarget.celsius(target_temp),
|
||||
heat_mode=HeatMode.HEAT_ON)
|
||||
|
||||
def set_fan_mode(self, fan_mode):
|
||||
"""Set new fan mode."""
|
||||
_LOGGER.debug("Set %s focus mode %s", self.name, fan_mode)
|
||||
from libpurecoollink.const import FocusMode
|
||||
if fan_mode == STATE_FOCUS:
|
||||
self._device.set_configuration(focus_mode=FocusMode.FOCUS_ON)
|
||||
elif fan_mode == STATE_DIFFUSE:
|
||||
self._device.set_configuration(focus_mode=FocusMode.FOCUS_OFF)
|
||||
|
||||
def set_operation_mode(self, operation_mode):
|
||||
"""Set operation mode."""
|
||||
_LOGGER.debug("Set %s heat mode %s", self.name, operation_mode)
|
||||
from libpurecoollink.const import HeatMode
|
||||
if operation_mode == STATE_HEAT:
|
||||
self._device.set_configuration(heat_mode=HeatMode.HEAT_ON)
|
||||
elif operation_mode == STATE_COOL:
|
||||
self._device.set_configuration(heat_mode=HeatMode.HEAT_OFF)
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
"""Return the minimum temperature."""
|
||||
return 1
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
"""Return the maximum temperature."""
|
||||
return 37
|
@ -102,5 +102,6 @@ def setup(hass, config):
|
||||
discovery.load_platform(hass, "sensor", DOMAIN, {}, config)
|
||||
discovery.load_platform(hass, "fan", DOMAIN, {}, config)
|
||||
discovery.load_platform(hass, "vacuum", DOMAIN, {}, config)
|
||||
discovery.load_platform(hass, "climate", DOMAIN, {}, config)
|
||||
|
||||
return True
|
||||
|
358
tests/components/climate/test_dyson.py
Normal file
358
tests/components/climate/test_dyson.py
Normal file
@ -0,0 +1,358 @@
|
||||
"""Test the Dyson fan component."""
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from libpurecoollink.const import (FocusMode, HeatMode, HeatState, HeatTarget,
|
||||
TiltState)
|
||||
from libpurecoollink.dyson_pure_state import DysonPureHotCoolState
|
||||
from libpurecoollink.dyson_pure_hotcool_link import DysonPureHotCoolLink
|
||||
from homeassistant.components.climate import dyson
|
||||
from homeassistant.components import dyson as dyson_parent
|
||||
from homeassistant.const import TEMP_CELSIUS, ATTR_TEMPERATURE
|
||||
from homeassistant.setup import setup_component
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
class MockDysonState(DysonPureHotCoolState):
|
||||
"""Mock Dyson state."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create new Mock Dyson State."""
|
||||
pass
|
||||
|
||||
|
||||
def _get_device_with_no_state():
|
||||
"""Return a device with no state."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state = None
|
||||
device.environmental_state = None
|
||||
return device
|
||||
|
||||
|
||||
def _get_device_off():
|
||||
"""Return a device with state off."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state = mock.Mock()
|
||||
device.environmental_state = mock.Mock()
|
||||
return device
|
||||
|
||||
|
||||
def _get_device_focus():
|
||||
"""Return a device with fan state of focus mode."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state.focus_mode = FocusMode.FOCUS_ON.value
|
||||
return device
|
||||
|
||||
|
||||
def _get_device_diffuse():
|
||||
"""Return a device with fan state of diffuse mode."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state.focus_mode = FocusMode.FOCUS_OFF.value
|
||||
return device
|
||||
|
||||
|
||||
def _get_device_cool():
|
||||
"""Return a device with state of cooling."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state.tilt = TiltState.TILT_FALSE.value
|
||||
device.state.focus_mode = FocusMode.FOCUS_OFF.value
|
||||
device.state.heat_target = HeatTarget.celsius(12)
|
||||
device.state.heat_mode = HeatMode.HEAT_OFF.value
|
||||
device.state.heat_state = HeatState.HEAT_STATE_OFF.value
|
||||
device.environmental_state.temperature = 288
|
||||
device.environmental_state.humidity = 53
|
||||
return device
|
||||
|
||||
|
||||
def _get_device_heat_off():
|
||||
"""Return a device with state of heat reached target."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state = mock.Mock()
|
||||
device.state.tilt = TiltState.TILT_FALSE.value
|
||||
device.state.focus_mode = FocusMode.FOCUS_ON.value
|
||||
device.state.heat_target = HeatTarget.celsius(20)
|
||||
device.state.heat_mode = HeatMode.HEAT_ON.value
|
||||
device.state.heat_state = HeatState.HEAT_STATE_OFF.value
|
||||
device.environmental_state.temperature = 293
|
||||
device.environmental_state.humidity = 53
|
||||
return device
|
||||
|
||||
|
||||
def _get_device_heat_on():
|
||||
"""Return a device with state of heating."""
|
||||
device = mock.Mock(spec=DysonPureHotCoolLink)
|
||||
device.name = "Device_name"
|
||||
device.state = mock.Mock()
|
||||
device.state.tilt = TiltState.TILT_FALSE.value
|
||||
device.state.focus_mode = FocusMode.FOCUS_ON.value
|
||||
device.state.heat_target = HeatTarget.celsius(23)
|
||||
device.state.heat_mode = HeatMode.HEAT_ON.value
|
||||
device.state.heat_state = HeatState.HEAT_STATE_ON.value
|
||||
device.environmental_state.temperature = 289
|
||||
device.environmental_state.humidity = 53
|
||||
return device
|
||||
|
||||
|
||||
class DysonTest(unittest.TestCase):
|
||||
"""Dyson Climate component test class."""
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Set up things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
@mock.patch('libpurecoollink.dyson.DysonAccount.devices',
|
||||
return_value=[_get_device_heat_on(), _get_device_cool()])
|
||||
@mock.patch('libpurecoollink.dyson.DysonAccount.login', return_value=True)
|
||||
def test_setup_component_with_parent_discovery(self, mocked_login,
|
||||
mocked_devices):
|
||||
"""Test setup_component using discovery."""
|
||||
setup_component(self.hass, dyson_parent.DOMAIN, {
|
||||
dyson_parent.DOMAIN: {
|
||||
dyson_parent.CONF_USERNAME: "email",
|
||||
dyson_parent.CONF_PASSWORD: "password",
|
||||
dyson_parent.CONF_LANGUAGE: "US",
|
||||
}
|
||||
})
|
||||
self.assertEqual(len(self.hass.data[dyson.DYSON_DEVICES]), 2)
|
||||
self.hass.block_till_done()
|
||||
for m in mocked_devices.return_value:
|
||||
assert m.add_message_listener.called
|
||||
|
||||
def test_setup_component_without_devices(self):
|
||||
"""Test setup component with no devices."""
|
||||
self.hass.data[dyson.DYSON_DEVICES] = []
|
||||
add_devices = mock.MagicMock()
|
||||
dyson.setup_platform(self.hass, None, add_devices)
|
||||
add_devices.assert_not_called()
|
||||
|
||||
def test_setup_component_with_devices(self):
|
||||
"""Test setup component with valid devices."""
|
||||
devices = [
|
||||
_get_device_with_no_state(),
|
||||
_get_device_off(),
|
||||
_get_device_heat_on()
|
||||
]
|
||||
self.hass.data[dyson.DYSON_DEVICES] = devices
|
||||
add_devices = mock.MagicMock()
|
||||
dyson.setup_platform(self.hass, None, add_devices, discovery_info={})
|
||||
self.assertTrue(add_devices.called)
|
||||
|
||||
def test_setup_component_with_invalid_devices(self):
|
||||
"""Test setup component with invalid devices."""
|
||||
devices = [
|
||||
None,
|
||||
"foo_bar"
|
||||
]
|
||||
self.hass.data[dyson.DYSON_DEVICES] = devices
|
||||
add_devices = mock.MagicMock()
|
||||
dyson.setup_platform(self.hass, None, add_devices, discovery_info={})
|
||||
add_devices.assert_called_with([])
|
||||
|
||||
def test_setup_component(self):
|
||||
"""Test setup component with devices."""
|
||||
device_fan = _get_device_heat_on()
|
||||
device_non_fan = _get_device_off()
|
||||
|
||||
def _add_device(devices):
|
||||
assert len(devices) == 1
|
||||
assert devices[0].name == "Device_name"
|
||||
|
||||
self.hass.data[dyson.DYSON_DEVICES] = [device_fan, device_non_fan]
|
||||
dyson.setup_platform(self.hass, None, _add_device)
|
||||
|
||||
def test_dyson_set_temperature(self):
|
||||
"""Test set climate temperature."""
|
||||
device = _get_device_heat_on()
|
||||
device.temp_unit = TEMP_CELSIUS
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertFalse(entity.should_poll)
|
||||
|
||||
# Without target temp.
|
||||
kwargs = {}
|
||||
entity.set_temperature(**kwargs)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_not_called()
|
||||
|
||||
kwargs = {ATTR_TEMPERATURE: 23}
|
||||
entity.set_temperature(**kwargs)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(
|
||||
heat_mode=HeatMode.HEAT_ON,
|
||||
heat_target=HeatTarget.celsius(23))
|
||||
|
||||
# Should clip the target temperature between 1 and 37 inclusive.
|
||||
kwargs = {ATTR_TEMPERATURE: 50}
|
||||
entity.set_temperature(**kwargs)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(
|
||||
heat_mode=HeatMode.HEAT_ON,
|
||||
heat_target=HeatTarget.celsius(37))
|
||||
|
||||
kwargs = {ATTR_TEMPERATURE: -5}
|
||||
entity.set_temperature(**kwargs)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(
|
||||
heat_mode=HeatMode.HEAT_ON,
|
||||
heat_target=HeatTarget.celsius(1))
|
||||
|
||||
def test_dyson_set_temperature_when_cooling_mode(self):
|
||||
"""Test set climate temperature when heating is off."""
|
||||
device = _get_device_cool()
|
||||
device.temp_unit = TEMP_CELSIUS
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
entity.schedule_update_ha_state = mock.Mock()
|
||||
|
||||
kwargs = {ATTR_TEMPERATURE: 23}
|
||||
entity.set_temperature(**kwargs)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(
|
||||
heat_mode=HeatMode.HEAT_ON,
|
||||
heat_target=HeatTarget.celsius(23))
|
||||
|
||||
def test_dyson_set_fan_mode(self):
|
||||
"""Test set fan mode."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertFalse(entity.should_poll)
|
||||
|
||||
entity.set_fan_mode(dyson.STATE_FOCUS)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(focus_mode=FocusMode.FOCUS_ON)
|
||||
|
||||
entity.set_fan_mode(dyson.STATE_DIFFUSE)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(focus_mode=FocusMode.FOCUS_OFF)
|
||||
|
||||
def test_dyson_fan_list(self):
|
||||
"""Test get fan list."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(len(entity.fan_list), 2)
|
||||
self.assertTrue(dyson.STATE_FOCUS in entity.fan_list)
|
||||
self.assertTrue(dyson.STATE_DIFFUSE in entity.fan_list)
|
||||
|
||||
def test_dyson_fan_mode_focus(self):
|
||||
"""Test fan focus mode."""
|
||||
device = _get_device_focus()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_fan_mode, dyson.STATE_FOCUS)
|
||||
|
||||
def test_dyson_fan_mode_diffuse(self):
|
||||
"""Test fan diffuse mode."""
|
||||
device = _get_device_diffuse()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_fan_mode, dyson.STATE_DIFFUSE)
|
||||
|
||||
def test_dyson_set_operation_mode(self):
|
||||
"""Test set operation mode."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertFalse(entity.should_poll)
|
||||
|
||||
entity.set_operation_mode(dyson.STATE_HEAT)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(heat_mode=HeatMode.HEAT_ON)
|
||||
|
||||
entity.set_operation_mode(dyson.STATE_COOL)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(heat_mode=HeatMode.HEAT_OFF)
|
||||
|
||||
def test_dyson_operation_list(self):
|
||||
"""Test get operation list."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(len(entity.operation_list), 2)
|
||||
self.assertTrue(dyson.STATE_HEAT in entity.operation_list)
|
||||
self.assertTrue(dyson.STATE_COOL in entity.operation_list)
|
||||
|
||||
def test_dyson_heat_off(self):
|
||||
"""Test turn off heat."""
|
||||
device = _get_device_heat_off()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
entity.set_operation_mode(dyson.STATE_COOL)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(heat_mode=HeatMode.HEAT_OFF)
|
||||
|
||||
def test_dyson_heat_on(self):
|
||||
"""Test turn on heat."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
entity.set_operation_mode(dyson.STATE_HEAT)
|
||||
set_config = device.set_configuration
|
||||
set_config.assert_called_with(heat_mode=HeatMode.HEAT_ON)
|
||||
|
||||
def test_dyson_heat_value_on(self):
|
||||
"""Test get heat value on."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_operation, dyson.STATE_HEAT)
|
||||
|
||||
def test_dyson_heat_value_off(self):
|
||||
"""Test get heat value off."""
|
||||
device = _get_device_cool()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_operation, dyson.STATE_COOL)
|
||||
|
||||
def test_dyson_heat_value_idle(self):
|
||||
"""Test get heat value idle."""
|
||||
device = _get_device_heat_off()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_operation, dyson.STATE_IDLE)
|
||||
|
||||
def test_on_message(self):
|
||||
"""Test when message is received."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
entity.schedule_update_ha_state = mock.Mock()
|
||||
entity.on_message(MockDysonState())
|
||||
entity.schedule_update_ha_state.assert_called_with()
|
||||
|
||||
def test_general_properties(self):
|
||||
"""Test properties of entity."""
|
||||
device = _get_device_with_no_state()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.should_poll, False)
|
||||
self.assertEqual(entity.supported_features, dyson.SUPPORT_FLAGS)
|
||||
self.assertEqual(entity.temperature_unit, TEMP_CELSIUS)
|
||||
|
||||
def test_property_current_humidity(self):
|
||||
"""Test properties of current humidity."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_humidity, 53)
|
||||
|
||||
def test_property_current_humidity_with_invalid_env_state(self):
|
||||
"""Test properties of current humidity with invalid env state."""
|
||||
device = _get_device_off()
|
||||
device.environmental_state.humidity = 0
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_humidity, None)
|
||||
|
||||
def test_property_current_humidity_without_env_state(self):
|
||||
"""Test properties of current humidity without env state."""
|
||||
device = _get_device_with_no_state()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.current_humidity, None)
|
||||
|
||||
def test_property_current_temperature(self):
|
||||
"""Test properties of current temperature."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
# Result should be in celsius, hence then subtraction of 273.
|
||||
self.assertEqual(entity.current_temperature, 289 - 273)
|
||||
|
||||
def test_property_target_temperature(self):
|
||||
"""Test properties of target temperature."""
|
||||
device = _get_device_heat_on()
|
||||
entity = dyson.DysonPureHotCoolLinkDevice(device)
|
||||
self.assertEqual(entity.target_temperature, 23)
|
@ -87,7 +87,7 @@ class DysonTest(unittest.TestCase):
|
||||
self.assertEqual(mocked_login.call_count, 1)
|
||||
self.assertEqual(mocked_devices.call_count, 1)
|
||||
self.assertEqual(len(self.hass.data[dyson.DYSON_DEVICES]), 1)
|
||||
self.assertEqual(mocked_discovery.call_count, 3)
|
||||
self.assertEqual(mocked_discovery.call_count, 4)
|
||||
|
||||
@mock.patch('libpurecoollink.dyson.DysonAccount.devices',
|
||||
return_value=[_get_dyson_account_device_not_available()])
|
||||
@ -172,7 +172,7 @@ class DysonTest(unittest.TestCase):
|
||||
self.assertEqual(mocked_login.call_count, 1)
|
||||
self.assertEqual(mocked_devices.call_count, 1)
|
||||
self.assertEqual(len(self.hass.data[dyson.DYSON_DEVICES]), 1)
|
||||
self.assertEqual(mocked_discovery.call_count, 3)
|
||||
self.assertEqual(mocked_discovery.call_count, 4)
|
||||
|
||||
@mock.patch('libpurecoollink.dyson.DysonAccount.devices',
|
||||
return_value=[_get_dyson_account_device_not_available()])
|
||||
|
Loading…
x
Reference in New Issue
Block a user