"""Test the Dyson fan component.""" import json import unittest from unittest import mock import asynctest from libpurecool.const import FanMode, FanSpeed, NightMode, Oscillation from libpurecool.dyson_pure_cool import DysonPureCool from libpurecool.dyson_pure_cool_link import DysonPureCoolLink from libpurecool.dyson_pure_state import DysonPureCoolState from libpurecool.dyson_pure_state_v2 import DysonPureCoolV2State from homeassistant.components import dyson as dyson_parent from homeassistant.components.dyson import DYSON_DEVICES import homeassistant.components.dyson.fan as dyson from homeassistant.components.fan import ( ATTR_OSCILLATING, ATTR_SPEED, DOMAIN, SERVICE_OSCILLATE, SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM, ) from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON from homeassistant.helpers import discovery from homeassistant.setup import async_setup_component from tests.common import get_test_home_assistant class MockDysonState(DysonPureCoolState): """Mock Dyson state.""" def __init__(self): """Create new Mock Dyson State.""" pass def _get_dyson_purecool_device(): """Return a valid device as provided by the Dyson web services.""" device = mock.Mock(spec=DysonPureCool) device.serial = "XX-XXXXX-XX" device.name = "Living room" device.connect = mock.Mock(return_value=True) device.auto_connect = mock.Mock(return_value=True) device.state = mock.Mock() device.state.oscillation = "OION" device.state.fan_power = "ON" device.state.speed = FanSpeed.FAN_SPEED_AUTO.value device.state.night_mode = "OFF" device.state.auto_mode = "ON" device.state.oscillation_angle_low = "0090" device.state.oscillation_angle_high = "0180" device.state.front_direction = "ON" device.state.sleep_timer = 60 device.state.hepa_filter_state = "0090" device.state.carbon_filter_state = "0080" return device def _get_dyson_purecoollink_device(): """Return a valid device as provided by the Dyson web services.""" device = mock.Mock(spec=DysonPureCoolLink) device.serial = "XX-XXXXX-XX" device.name = "Living room" device.connect = mock.Mock(return_value=True) device.auto_connect = mock.Mock(return_value=True) device.state = mock.Mock() device.state.oscillation = "ON" device.state.fan_mode = "FAN" device.state.speed = FanSpeed.FAN_SPEED_AUTO.value device.state.night_mode = "OFF" return device def _get_supported_speeds(): return [ int(FanSpeed.FAN_SPEED_1.value), int(FanSpeed.FAN_SPEED_2.value), int(FanSpeed.FAN_SPEED_3.value), int(FanSpeed.FAN_SPEED_4.value), int(FanSpeed.FAN_SPEED_5.value), int(FanSpeed.FAN_SPEED_6.value), int(FanSpeed.FAN_SPEED_7.value), int(FanSpeed.FAN_SPEED_8.value), int(FanSpeed.FAN_SPEED_9.value), int(FanSpeed.FAN_SPEED_10.value), ] def _get_config(): """Return a config dictionary.""" return { dyson_parent.DOMAIN: { dyson_parent.CONF_USERNAME: "email", dyson_parent.CONF_PASSWORD: "password", dyson_parent.CONF_LANGUAGE: "GB", dyson_parent.CONF_DEVICES: [ {"device_id": "XX-XXXXX-XX", "device_ip": "192.168.0.1"} ], } } def _get_device_with_no_state(): """Return a device with no state.""" device = mock.Mock() device.name = "Device_name" device.state = None return device def _get_device_off(): """Return a device with state off.""" device = mock.Mock() device.name = "Device_name" device.state = mock.Mock() device.state.fan_mode = "OFF" device.state.night_mode = "ON" device.state.speed = "0004" return device def _get_device_auto(): """Return a device with state auto.""" device = mock.Mock() device.name = "Device_name" device.state = mock.Mock() device.state.fan_mode = "AUTO" device.state.night_mode = "ON" device.state.speed = "AUTO" return device def _get_device_on(): """Return a valid state on.""" device = mock.Mock(spec=DysonPureCoolLink) device.name = "Device_name" device.state = mock.Mock() device.state.fan_mode = "FAN" device.state.fan_state = "FAN" device.state.oscillation = "ON" device.state.night_mode = "OFF" device.state.speed = "0001" return device class DysonSetupTest(unittest.TestCase): """Dyson component setup tests.""" 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() def test_setup_component_with_no_devices(self): """Test setup component with no devices.""" self.hass.data[dyson.DYSON_DEVICES] = [] add_entities = mock.MagicMock() dyson.setup_platform(self.hass, None, add_entities, mock.Mock()) add_entities.assert_called_with([]) def test_setup_component(self): """Test setup component with devices.""" def _add_device(devices): assert len(devices) == 2 assert devices[0].name == "Device_name" device_fan = _get_device_on() device_purecool_fan = _get_dyson_purecool_device() device_non_fan = _get_device_off() self.hass.data[dyson.DYSON_DEVICES] = [ device_fan, device_purecool_fan, device_non_fan, ] dyson.setup_platform(self.hass, None, _add_device) class DysonTest(unittest.TestCase): """Dyson fan 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() def test_dyson_set_speed(self): """Test set fan speed.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.should_poll component.set_speed("1") set_config = device.set_configuration set_config.assert_called_with( fan_mode=FanMode.FAN, fan_speed=FanSpeed.FAN_SPEED_1 ) component.set_speed("AUTO") set_config = device.set_configuration set_config.assert_called_with(fan_mode=FanMode.AUTO) def test_dyson_turn_on(self): """Test turn on fan.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.should_poll component.turn_on() set_config = device.set_configuration set_config.assert_called_with(fan_mode=FanMode.FAN) def test_dyson_turn_night_mode(self): """Test turn on fan with night mode.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.should_poll component.set_night_mode(True) set_config = device.set_configuration set_config.assert_called_with(night_mode=NightMode.NIGHT_MODE_ON) component.set_night_mode(False) set_config = device.set_configuration set_config.assert_called_with(night_mode=NightMode.NIGHT_MODE_OFF) def test_is_night_mode(self): """Test night mode.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.night_mode device = _get_device_off() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.night_mode def test_dyson_turn_auto_mode(self): """Test turn on/off fan with auto mode.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.should_poll component.set_auto_mode(True) set_config = device.set_configuration set_config.assert_called_with(fan_mode=FanMode.AUTO) component.set_auto_mode(False) set_config = device.set_configuration set_config.assert_called_with(fan_mode=FanMode.FAN) def test_is_auto_mode(self): """Test auto mode.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.auto_mode device = _get_device_auto() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.auto_mode def test_dyson_turn_on_speed(self): """Test turn on fan with specified speed.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.should_poll component.turn_on("1") set_config = device.set_configuration set_config.assert_called_with( fan_mode=FanMode.FAN, fan_speed=FanSpeed.FAN_SPEED_1 ) component.turn_on("AUTO") set_config = device.set_configuration set_config.assert_called_with(fan_mode=FanMode.AUTO) def test_dyson_turn_off(self): """Test turn off fan.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.should_poll component.turn_off() set_config = device.set_configuration set_config.assert_called_with(fan_mode=FanMode.OFF) def test_dyson_oscillate_off(self): """Test turn off oscillation.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) component.oscillate(False) set_config = device.set_configuration set_config.assert_called_with(oscillation=Oscillation.OSCILLATION_OFF) def test_dyson_oscillate_on(self): """Test turn on oscillation.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) component.oscillate(True) set_config = device.set_configuration set_config.assert_called_with(oscillation=Oscillation.OSCILLATION_ON) def test_dyson_oscillate_value_on(self): """Test get oscillation value on.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.oscillating def test_dyson_oscillate_value_off(self): """Test get oscillation value off.""" device = _get_device_off() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.oscillating def test_dyson_on(self): """Test device is on.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.is_on def test_dyson_off(self): """Test device is off.""" device = _get_device_off() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.is_on device = _get_device_with_no_state() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert not component.is_on def test_dyson_get_speed(self): """Test get device speed.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.speed == 1 device = _get_device_off() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.speed == 4 device = _get_device_with_no_state() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.speed is None device = _get_device_auto() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.speed == "AUTO" def test_dyson_get_direction(self): """Test get device direction.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.current_direction is None def test_dyson_get_speed_list(self): """Test get speeds list.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert len(component.speed_list) == 11 def test_dyson_supported_features(self): """Test supported features.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) assert component.supported_features == 3 def test_on_message(self): """Test when message is received.""" device = _get_device_on() component = dyson.DysonPureCoolLinkDevice(self.hass, device) component.entity_id = "entity_id" component.schedule_update_ha_state = mock.Mock() component.on_message(MockDysonState()) component.schedule_update_ha_state.assert_called_with() def test_service_set_night_mode(self): """Test set night mode service.""" dyson_device = mock.MagicMock() self.hass.data[DYSON_DEVICES] = [] dyson_device.entity_id = "fan.living_room" self.hass.data[dyson.DYSON_FAN_DEVICES] = [dyson_device] dyson.setup_platform(self.hass, None, mock.MagicMock(), mock.MagicMock()) self.hass.services.call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_NIGHT_MODE, {"entity_id": "fan.bed_room", "night_mode": True}, True, ) assert dyson_device.set_night_mode.call_count == 0 self.hass.services.call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_NIGHT_MODE, {"entity_id": "fan.living_room", "night_mode": True}, True, ) dyson_device.set_night_mode.assert_called_with(True) @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecoollink_device()], ) async def test_purecoollink_attributes(devices, login, hass): """Test state attributes.""" await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() fan_state = hass.states.get("fan.living_room") attributes = fan_state.attributes assert fan_state.state == "on" assert attributes[dyson.ATTR_NIGHT_MODE] is False assert attributes[ATTR_SPEED] == FanSpeed.FAN_SPEED_AUTO.value assert attributes[ATTR_OSCILLATING] is True @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_turn_on(devices, login, hass): """Test turn on.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "fan.bed_room"}, True ) assert device.turn_on.call_count == 0 await hass.services.async_call( DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "fan.living_room"}, True ) assert device.turn_on.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_speed(devices, login, hass): """Test set speed.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "fan.bed_room", ATTR_SPEED: SPEED_LOW}, True, ) assert device.set_fan_speed.call_count == 0 await hass.services.async_call( DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "fan.living_room", ATTR_SPEED: SPEED_LOW}, True, ) device.set_fan_speed.assert_called_with(FanSpeed.FAN_SPEED_4) await hass.services.async_call( DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "fan.living_room", ATTR_SPEED: SPEED_MEDIUM}, True, ) device.set_fan_speed.assert_called_with(FanSpeed.FAN_SPEED_7) await hass.services.async_call( DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "fan.living_room", ATTR_SPEED: SPEED_HIGH}, True, ) device.set_fan_speed.assert_called_with(FanSpeed.FAN_SPEED_10) @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_turn_off(devices, login, hass): """Test turn off.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "fan.bed_room"}, True ) assert device.turn_off.call_count == 0 await hass.services.async_call( DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "fan.living_room"}, True ) assert device.turn_off.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_dyson_speed(devices, login, hass): """Test set exact dyson speed.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_DYSON_SPEED, { ATTR_ENTITY_ID: "fan.bed_room", dyson.ATTR_DYSON_SPEED: int(FanSpeed.FAN_SPEED_2.value), }, True, ) assert device.set_fan_speed.call_count == 0 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_DYSON_SPEED, { ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_DYSON_SPEED: int(FanSpeed.FAN_SPEED_2.value), }, True, ) device.set_fan_speed.assert_called_with(FanSpeed.FAN_SPEED_2) @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_oscillate(devices, login, hass): """Test set oscillation.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( DOMAIN, SERVICE_OSCILLATE, {ATTR_ENTITY_ID: "fan.bed_room", ATTR_OSCILLATING: True}, True, ) assert device.enable_oscillation.call_count == 0 await hass.services.async_call( DOMAIN, SERVICE_OSCILLATE, {ATTR_ENTITY_ID: "fan.living_room", ATTR_OSCILLATING: True}, True, ) assert device.enable_oscillation.call_count == 1 await hass.services.async_call( DOMAIN, SERVICE_OSCILLATE, {ATTR_ENTITY_ID: "fan.living_room", ATTR_OSCILLATING: False}, True, ) assert device.disable_oscillation.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_night_mode(devices, login, hass): """Test set night mode.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_NIGHT_MODE, {"entity_id": "fan.bed_room", "night_mode": True}, True, ) assert device.enable_night_mode.call_count == 0 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_NIGHT_MODE, {"entity_id": "fan.living_room", "night_mode": True}, True, ) assert device.enable_night_mode.call_count == 1 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_NIGHT_MODE, {"entity_id": "fan.living_room", "night_mode": False}, True, ) assert device.disable_night_mode.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_auto_mode(devices, login, hass): """Test set auto mode.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_AUTO_MODE, {ATTR_ENTITY_ID: "fan.bed_room", dyson.ATTR_AUTO_MODE: True}, True, ) assert device.enable_auto_mode.call_count == 0 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_AUTO_MODE, {ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_AUTO_MODE: True}, True, ) assert device.enable_auto_mode.call_count == 1 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_AUTO_MODE, {ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_AUTO_MODE: False}, True, ) assert device.disable_auto_mode.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_angle(devices, login, hass): """Test set angle.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_ANGLE, { ATTR_ENTITY_ID: "fan.bed_room", dyson.ATTR_ANGLE_LOW: 90, dyson.ATTR_ANGLE_HIGH: 180, }, True, ) assert device.enable_oscillation.call_count == 0 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_ANGLE, { ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_ANGLE_LOW: 90, dyson.ATTR_ANGLE_HIGH: 180, }, True, ) device.enable_oscillation.assert_called_with(90, 180) @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_flow_direction_front(devices, login, hass): """Test set frontal flow direction.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_FLOW_DIRECTION_FRONT, {ATTR_ENTITY_ID: "fan.bed_room", dyson.ATTR_FLOW_DIRECTION_FRONT: True}, True, ) assert device.enable_frontal_direction.call_count == 0 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_FLOW_DIRECTION_FRONT, {ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_FLOW_DIRECTION_FRONT: True}, True, ) assert device.enable_frontal_direction.call_count == 1 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_FLOW_DIRECTION_FRONT, {ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_FLOW_DIRECTION_FRONT: False}, True, ) assert device.disable_frontal_direction.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_set_timer(devices, login, hass): """Test set timer.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_TIMER, {ATTR_ENTITY_ID: "fan.bed_room", dyson.ATTR_TIMER: 60}, True, ) assert device.enable_frontal_direction.call_count == 0 await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_TIMER, {ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_TIMER: 60}, True, ) device.enable_sleep_timer.assert_called_with(60) await hass.services.async_call( dyson.DYSON_DOMAIN, dyson.SERVICE_SET_TIMER, {ATTR_ENTITY_ID: "fan.living_room", dyson.ATTR_TIMER: 0}, True, ) assert device.disable_sleep_timer.call_count == 1 @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_update_state(devices, login, hass): """Test state update.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() event = { "msg": "CURRENT-STATE", "product-state": { "fpwr": "OFF", "fdir": "OFF", "auto": "OFF", "oscs": "ON", "oson": "ON", "nmod": "OFF", "rhtm": "ON", "fnst": "FAN", "ercd": "11E1", "wacd": "NONE", "nmdv": "0004", "fnsp": "0002", "bril": "0002", "corf": "ON", "cflr": "0085", "hflr": "0095", "sltm": "OFF", "osal": "0045", "osau": "0095", "ancp": "CUST", }, } device.state = DysonPureCoolV2State(json.dumps(event)) for call in device.add_message_listener.call_args_list: callback = call[0][0] if type(callback.__self__) == dyson.DysonPureCoolDevice: callback(device.state) await hass.async_block_till_done() fan_state = hass.states.get("fan.living_room") attributes = fan_state.attributes assert fan_state.state == "off" assert attributes[dyson.ATTR_NIGHT_MODE] is False assert attributes[dyson.ATTR_AUTO_MODE] is False assert attributes[dyson.ATTR_ANGLE_LOW] == 45 assert attributes[dyson.ATTR_ANGLE_HIGH] == 95 assert attributes[dyson.ATTR_FLOW_DIRECTION_FRONT] is False assert attributes[dyson.ATTR_TIMER] == "OFF" assert attributes[dyson.ATTR_HEPA_FILTER] == 95 assert attributes[dyson.ATTR_CARBON_FILTER] == 85 assert attributes[dyson.ATTR_DYSON_SPEED] == int(FanSpeed.FAN_SPEED_2.value) assert attributes[ATTR_SPEED] is SPEED_LOW assert attributes[ATTR_OSCILLATING] is False assert attributes[dyson.ATTR_DYSON_SPEED_LIST] == _get_supported_speeds() @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_update_state_filter_inv(devices, login, hass): """Test state TP06 carbon filter state.""" device = devices.return_value[0] await async_setup_component(hass, dyson.DYSON_DOMAIN, _get_config()) await hass.async_block_till_done() event = { "msg": "CURRENT-STATE", "product-state": { "fpwr": "OFF", "fdir": "ON", "auto": "ON", "oscs": "ON", "oson": "ON", "nmod": "ON", "rhtm": "ON", "fnst": "FAN", "ercd": "11E1", "wacd": "NONE", "nmdv": "0004", "fnsp": "0002", "bril": "0002", "corf": "ON", "cflr": "INV", "hflr": "0075", "sltm": "OFF", "osal": "0055", "osau": "0105", "ancp": "CUST", }, } device.state = DysonPureCoolV2State(json.dumps(event)) for call in device.add_message_listener.call_args_list: callback = call[0][0] if type(callback.__self__) == dyson.DysonPureCoolDevice: callback(device.state) await hass.async_block_till_done() fan_state = hass.states.get("fan.living_room") attributes = fan_state.attributes assert fan_state.state == "off" assert attributes[dyson.ATTR_NIGHT_MODE] is True assert attributes[dyson.ATTR_AUTO_MODE] is True assert attributes[dyson.ATTR_ANGLE_LOW] == 55 assert attributes[dyson.ATTR_ANGLE_HIGH] == 105 assert attributes[dyson.ATTR_FLOW_DIRECTION_FRONT] is True assert attributes[dyson.ATTR_TIMER] == "OFF" assert attributes[dyson.ATTR_HEPA_FILTER] == 75 assert attributes[dyson.ATTR_CARBON_FILTER] == "INV" assert attributes[dyson.ATTR_DYSON_SPEED] == int(FanSpeed.FAN_SPEED_2.value) assert attributes[ATTR_SPEED] is SPEED_LOW assert attributes[ATTR_OSCILLATING] is False assert attributes[dyson.ATTR_DYSON_SPEED_LIST] == _get_supported_speeds() @asynctest.patch("libpurecool.dyson.DysonAccount.login", return_value=True) @asynctest.patch( "libpurecool.dyson.DysonAccount.devices", return_value=[_get_dyson_purecool_device()], ) async def test_purecool_component_setup_only_once(devices, login, hass): """Test if entities are created only once.""" config = _get_config() await async_setup_component(hass, dyson_parent.DOMAIN, config) await hass.async_block_till_done() discovery.load_platform(hass, "fan", dyson_parent.DOMAIN, {}, config) await hass.async_block_till_done() fans = [ fan for fan in hass.data[DOMAIN].entities if fan.platform.platform_name == dyson_parent.DOMAIN ] assert len(fans) == 1 assert fans[0].device_serial == "XX-XXXXX-XX"