mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Update xiaomi vacuum tests and include in coverage (#8845)
* Fix tests for Demo vacuum platform (and increase coverage) * increase coverage of xiaomi vacuum tests and include in coverage Also little fixes * remove print statement
This commit is contained in:
parent
6e1785173f
commit
a221b10694
@ -197,7 +197,11 @@ omit =
|
||||
homeassistant/components/*/wink.py
|
||||
|
||||
homeassistant/components/xiaomi.py
|
||||
homeassistant/components/*/xiaomi.py
|
||||
homeassistant/components/binary_sensor/xiaomi.py
|
||||
homeassistant/components/cover/xiaomi.py
|
||||
homeassistant/components/light/xiaomi.py
|
||||
homeassistant/components/sensor/xiaomi.py
|
||||
homeassistant/components/switch/xiaomi.py
|
||||
|
||||
homeassistant/components/zabbix.py
|
||||
homeassistant/components/*/zabbix.py
|
||||
|
@ -184,9 +184,6 @@ def async_setup(hass, config):
|
||||
def async_handle_vacuum_service(service):
|
||||
"""Map services to methods on VacuumDevice."""
|
||||
method = SERVICE_TO_METHOD.get(service.service)
|
||||
if not method:
|
||||
return
|
||||
|
||||
target_vacuums = component.async_extract_from_service(service)
|
||||
params = service.data.copy()
|
||||
params.pop(ATTR_ENTITY_ID, None)
|
||||
@ -223,17 +220,17 @@ class VacuumDevice(ToggleEntity):
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag vacuum cleaner features that are supported."""
|
||||
return 0
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
"""Return the status of the vacuum cleaner."""
|
||||
return None
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def battery_level(self):
|
||||
"""Return the battery level of the vacuum cleaner."""
|
||||
return None
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def battery_icon(self):
|
||||
@ -247,12 +244,12 @@ class VacuumDevice(ToggleEntity):
|
||||
@property
|
||||
def fan_speed(self):
|
||||
"""Return the fan speed of the vacuum cleaner."""
|
||||
return None
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def fan_speed_list(self) -> list:
|
||||
def fan_speed_list(self):
|
||||
"""Get the list of available fan speed steps of the vacuum cleaner."""
|
||||
return []
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
|
@ -7,7 +7,7 @@ https://home-assistant.io/components/demo/
|
||||
import logging
|
||||
|
||||
from homeassistant.components.vacuum import (
|
||||
ATTR_CLEANED_AREA, DEFAULT_ICON, SUPPORT_BATTERY, SUPPORT_FAN_SPEED,
|
||||
ATTR_CLEANED_AREA, SUPPORT_BATTERY, SUPPORT_FAN_SPEED,
|
||||
SUPPORT_LOCATE, SUPPORT_PAUSE, SUPPORT_RETURN_HOME, SUPPORT_SEND_COMMAND,
|
||||
SUPPORT_STATUS, SUPPORT_STOP, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
|
||||
VacuumDevice)
|
||||
@ -32,6 +32,7 @@ DEMO_VACUUM_COMPLETE = '0_Ground_floor'
|
||||
DEMO_VACUUM_MOST = '1_First_floor'
|
||||
DEMO_VACUUM_BASIC = '2_Second_floor'
|
||||
DEMO_VACUUM_MINIMAL = '3_Third_floor'
|
||||
DEMO_VACUUM_NONE = '4_Fourth_floor'
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
@ -41,6 +42,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
DemoVacuum(DEMO_VACUUM_MOST, SUPPORT_MOST_SERVICES),
|
||||
DemoVacuum(DEMO_VACUUM_BASIC, SUPPORT_BASIC_SERVICES),
|
||||
DemoVacuum(DEMO_VACUUM_MINIMAL, SUPPORT_MINIMAL_SERVICES),
|
||||
DemoVacuum(DEMO_VACUUM_NONE, 0),
|
||||
])
|
||||
|
||||
|
||||
@ -48,7 +50,7 @@ class DemoVacuum(VacuumDevice):
|
||||
"""Representation of a demo vacuum."""
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def __init__(self, name, supported_features=None):
|
||||
def __init__(self, name, supported_features):
|
||||
"""Initialize the vacuum."""
|
||||
self._name = name
|
||||
self._supported_features = supported_features
|
||||
@ -66,7 +68,7 @@ class DemoVacuum(VacuumDevice):
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon for the vacuum."""
|
||||
return DEFAULT_ICON
|
||||
return 'mdi:roomba'
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
@ -97,9 +99,7 @@ class DemoVacuum(VacuumDevice):
|
||||
@property
|
||||
def fan_speed_list(self):
|
||||
"""Return the status of the vacuum."""
|
||||
if self.supported_features & SUPPORT_FAN_SPEED == 0:
|
||||
return
|
||||
|
||||
assert self.supported_features & SUPPORT_FAN_SPEED != 0
|
||||
return FAN_SPEEDS
|
||||
|
||||
@property
|
||||
@ -118,10 +118,7 @@ class DemoVacuum(VacuumDevice):
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
if self._supported_features is not None:
|
||||
return self._supported_features
|
||||
|
||||
return super().supported_features
|
||||
return self._supported_features
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the vacuum on."""
|
||||
|
@ -103,9 +103,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
def async_service_handler(service):
|
||||
"""Map services to methods on MiroboVacuum."""
|
||||
method = SERVICE_TO_METHOD.get(service.service)
|
||||
if not method:
|
||||
return
|
||||
|
||||
params = {key: value for key, value in service.data.items()
|
||||
if key != ATTR_ENTITY_ID}
|
||||
entity_ids = service.data.get(ATTR_ENTITY_ID)
|
||||
@ -191,19 +188,19 @@ class MiroboVacuum(VacuumDevice):
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the specific state attributes of this vacuum cleaner."""
|
||||
attrs = {}
|
||||
if self.vacuum_state is not None:
|
||||
attrs = {
|
||||
attrs.update({
|
||||
ATTR_DO_NOT_DISTURB:
|
||||
STATE_ON if self.vacuum_state.dnd else STATE_OFF,
|
||||
# Not working --> 'Cleaning mode':
|
||||
# STATE_ON if self.vacuum_state.in_cleaning else STATE_OFF,
|
||||
ATTR_CLEANING_TIME: str(self.vacuum_state.clean_time),
|
||||
ATTR_CLEANED_AREA: round(self.vacuum_state.clean_area, 2)}
|
||||
ATTR_CLEANED_AREA: round(self.vacuum_state.clean_area, 2)})
|
||||
if self.vacuum_state.got_error:
|
||||
attrs[ATTR_ERROR] = self.vacuum_state.error
|
||||
return attrs
|
||||
|
||||
return {}
|
||||
return attrs
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
@ -242,15 +239,15 @@ class MiroboVacuum(VacuumDevice):
|
||||
def async_turn_off(self, **kwargs):
|
||||
"""Turn the vacuum off and return to home."""
|
||||
yield from self.async_stop()
|
||||
return_home = yield from self.async_return_to_base()
|
||||
if return_home:
|
||||
self._is_on = False
|
||||
yield from self.async_return_to_base()
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_stop(self, **kwargs):
|
||||
"""Stop the vacuum cleaner."""
|
||||
yield from self._try_command(
|
||||
stopped = yield from self._try_command(
|
||||
"Unable to stop: %s", self._vacuum.stop)
|
||||
if stopped:
|
||||
self._is_on = False
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_set_fan_speed(self, fan_speed, **kwargs):
|
||||
@ -338,17 +335,16 @@ class MiroboVacuum(VacuumDevice):
|
||||
@asyncio.coroutine
|
||||
def async_update(self):
|
||||
"""Fetch state from the device."""
|
||||
from mirobo import DeviceException
|
||||
from mirobo import VacuumException
|
||||
try:
|
||||
state = yield from self.hass.async_add_job(self._vacuum.status)
|
||||
|
||||
_LOGGER.debug("Got new state from the vacuum: %s", state.data)
|
||||
self.vacuum_state = state
|
||||
self._is_on = state.is_on
|
||||
self._available = True
|
||||
except DeviceException as ex:
|
||||
_LOGGER.warning("Got exception while fetching the state: %s", ex)
|
||||
except OSError as exc:
|
||||
_LOGGER.error("Got OSError while fetching the state: %s", exc)
|
||||
# self._available = False
|
||||
except OSError as ex:
|
||||
_LOGGER.error("Got exception while fetching the state: %s", ex)
|
||||
except VacuumException as exc:
|
||||
_LOGGER.warning("Got exception while fetching the state: %s", exc)
|
||||
# self._available = False
|
||||
|
@ -9,7 +9,7 @@ from homeassistant.components.vacuum import (
|
||||
SERVICE_SEND_COMMAND, SERVICE_SET_FAN_SPEED)
|
||||
from homeassistant.components.vacuum.demo import (
|
||||
DEMO_VACUUM_BASIC, DEMO_VACUUM_COMPLETE, DEMO_VACUUM_MINIMAL,
|
||||
DEMO_VACUUM_MOST, FAN_SPEEDS)
|
||||
DEMO_VACUUM_MOST, DEMO_VACUUM_NONE, FAN_SPEEDS)
|
||||
from homeassistant.const import (
|
||||
ATTR_SUPPORTED_FEATURES, CONF_PLATFORM, STATE_OFF, STATE_ON)
|
||||
from homeassistant.setup import setup_component
|
||||
@ -20,6 +20,7 @@ ENTITY_VACUUM_BASIC = '{}.{}'.format(DOMAIN, DEMO_VACUUM_BASIC).lower()
|
||||
ENTITY_VACUUM_COMPLETE = '{}.{}'.format(DOMAIN, DEMO_VACUUM_COMPLETE).lower()
|
||||
ENTITY_VACUUM_MINIMAL = '{}.{}'.format(DOMAIN, DEMO_VACUUM_MINIMAL).lower()
|
||||
ENTITY_VACUUM_MOST = '{}.{}'.format(DOMAIN, DEMO_VACUUM_MOST).lower()
|
||||
ENTITY_VACUUM_NONE = '{}.{}'.format(DOMAIN, DEMO_VACUUM_NONE).lower()
|
||||
|
||||
|
||||
class TestVacuumDemo(unittest.TestCase):
|
||||
@ -70,18 +71,30 @@ class TestVacuumDemo(unittest.TestCase):
|
||||
self.assertEqual(None, state.attributes.get(ATTR_FAN_SPEED_LIST))
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
||||
state = self.hass.states.get(ENTITY_VACUUM_NONE)
|
||||
self.assertEqual(0, state.attributes.get(ATTR_SUPPORTED_FEATURES))
|
||||
self.assertEqual(None, state.attributes.get(ATTR_STATUS))
|
||||
self.assertEqual(None, state.attributes.get(ATTR_BATTERY_LEVEL))
|
||||
self.assertEqual(None, state.attributes.get(ATTR_FAN_SPEED))
|
||||
self.assertEqual(None, state.attributes.get(ATTR_FAN_SPEED_LIST))
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
||||
def test_methods(self):
|
||||
"""Test if methods call the services as expected."""
|
||||
self.hass.states.set(ENTITY_VACUUM_BASIC, STATE_ON)
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(vacuum.is_on(self.hass, ENTITY_VACUUM_BASIC))
|
||||
|
||||
self.hass.states.set(ENTITY_VACUUM_BASIC, STATE_OFF)
|
||||
self.hass.block_till_done()
|
||||
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_BASIC))
|
||||
|
||||
self.hass.states.set(ENTITY_ID_ALL_VACUUMS, STATE_ON)
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(vacuum.is_on(self.hass))
|
||||
|
||||
self.hass.states.set(ENTITY_ID_ALL_VACUUMS, STATE_OFF)
|
||||
self.hass.block_till_done()
|
||||
self.assertFalse(vacuum.is_on(self.hass))
|
||||
|
||||
vacuum.turn_on(self.hass, ENTITY_VACUUM_COMPLETE)
|
||||
@ -128,6 +141,54 @@ class TestVacuumDemo(unittest.TestCase):
|
||||
state = self.hass.states.get(ENTITY_VACUUM_COMPLETE)
|
||||
self.assertEqual(FAN_SPEEDS[-1], state.attributes.get(ATTR_FAN_SPEED))
|
||||
|
||||
def test_unsupported_methods(self):
|
||||
"""Test service calls for unsupported vacuums."""
|
||||
self.hass.states.set(ENTITY_VACUUM_NONE, STATE_ON)
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
vacuum.turn_off(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
vacuum.stop(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
self.assertTrue(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
self.hass.states.set(ENTITY_VACUUM_NONE, STATE_OFF)
|
||||
self.hass.block_till_done()
|
||||
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
vacuum.turn_on(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
vacuum.toggle(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
# Non supported methods:
|
||||
vacuum.start_pause(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_NONE))
|
||||
|
||||
vacuum.locate(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
state = self.hass.states.get(ENTITY_VACUUM_NONE)
|
||||
self.assertIsNone(state.attributes.get(ATTR_STATUS))
|
||||
|
||||
vacuum.return_to_base(self.hass, ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
state = self.hass.states.get(ENTITY_VACUUM_NONE)
|
||||
self.assertIsNone(state.attributes.get(ATTR_STATUS))
|
||||
|
||||
vacuum.set_fan_speed(self.hass, FAN_SPEEDS[-1],
|
||||
entity_id=ENTITY_VACUUM_NONE)
|
||||
self.hass.block_till_done()
|
||||
state = self.hass.states.get(ENTITY_VACUUM_NONE)
|
||||
self.assertNotEqual(FAN_SPEEDS[-1],
|
||||
state.attributes.get(ATTR_FAN_SPEED))
|
||||
|
||||
def test_services(self):
|
||||
"""Test vacuum services."""
|
||||
# Test send_command
|
||||
|
@ -9,7 +9,7 @@ from homeassistant.components.vacuum import (
|
||||
ATTR_BATTERY_ICON,
|
||||
ATTR_FAN_SPEED, ATTR_FAN_SPEED_LIST, DOMAIN,
|
||||
SERVICE_LOCATE, SERVICE_RETURN_TO_BASE, SERVICE_SEND_COMMAND,
|
||||
SERVICE_SET_FAN_SPEED, SERVICE_STOP,
|
||||
SERVICE_SET_FAN_SPEED, SERVICE_START_PAUSE, SERVICE_STOP,
|
||||
SERVICE_TOGGLE, SERVICE_TURN_OFF, SERVICE_TURN_ON)
|
||||
from homeassistant.components.vacuum.xiaomi import (
|
||||
ATTR_CLEANED_AREA, ATTR_CLEANING_TIME, ATTR_DO_NOT_DISTURB, ATTR_ERROR,
|
||||
@ -17,18 +17,20 @@ from homeassistant.components.vacuum.xiaomi import (
|
||||
SERVICE_MOVE_REMOTE_CONTROL, SERVICE_MOVE_REMOTE_CONTROL_STEP,
|
||||
SERVICE_START_REMOTE_CONTROL, SERVICE_STOP_REMOTE_CONTROL)
|
||||
from homeassistant.const import (
|
||||
ATTR_SUPPORTED_FEATURES, CONF_PLATFORM, STATE_OFF, STATE_ON)
|
||||
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, CONF_PLATFORM, STATE_OFF,
|
||||
STATE_ON)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_mirobo():
|
||||
def mock_mirobo_is_off():
|
||||
"""Mock mock_mirobo."""
|
||||
mock_vacuum = mock.MagicMock()
|
||||
mock_vacuum.Vacuum().status().data = {'test': 'raw'}
|
||||
mock_vacuum.Vacuum().status().is_on = False
|
||||
mock_vacuum.Vacuum().status().fanspeed = 38
|
||||
mock_vacuum.Vacuum().status().got_error = False
|
||||
mock_vacuum.Vacuum().status().got_error = True
|
||||
mock_vacuum.Vacuum().status().error = 'Error message'
|
||||
mock_vacuum.Vacuum().status().dnd = True
|
||||
mock_vacuum.Vacuum().status().battery = 82
|
||||
mock_vacuum.Vacuum().status().clean_area = 123.43218
|
||||
@ -42,10 +44,59 @@ def mock_mirobo():
|
||||
yield mock_vacuum
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_mirobo_is_on():
|
||||
"""Mock mock_mirobo."""
|
||||
mock_vacuum = mock.MagicMock()
|
||||
mock_vacuum.Vacuum().status().data = {'test': 'raw'}
|
||||
mock_vacuum.Vacuum().status().is_on = True
|
||||
mock_vacuum.Vacuum().status().fanspeed = 99
|
||||
mock_vacuum.Vacuum().status().got_error = False
|
||||
mock_vacuum.Vacuum().status().dnd = False
|
||||
mock_vacuum.Vacuum().status().battery = 32
|
||||
mock_vacuum.Vacuum().status().clean_area = 133.43218
|
||||
mock_vacuum.Vacuum().status().clean_time = timedelta(
|
||||
hours=2, minutes=55, seconds=34)
|
||||
mock_vacuum.Vacuum().status().state = 'Test Xiaomi Cleaning'
|
||||
|
||||
with mock.patch.dict('sys.modules', {
|
||||
'mirobo': mock_vacuum,
|
||||
}):
|
||||
yield mock_vacuum
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_mirobo_errors():
|
||||
"""Mock mock_mirobo_errors to simulate a bad vacuum status request."""
|
||||
mock_vacuum = mock.MagicMock()
|
||||
mock_vacuum.Vacuum().status.side_effect = OSError()
|
||||
with mock.patch.dict('sys.modules', {
|
||||
'mirobo': mock_vacuum,
|
||||
}):
|
||||
yield mock_vacuum
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_xiaomi_vacuum(hass, caplog, mock_mirobo):
|
||||
def test_xiaomi_exceptions(hass, caplog, mock_mirobo_errors):
|
||||
"""Test vacuum supported features."""
|
||||
entity_name = 'test_vacuum_cleaner'
|
||||
entity_name = 'test_vacuum_cleaner_error'
|
||||
yield from async_setup_component(
|
||||
hass, DOMAIN,
|
||||
{DOMAIN: {CONF_PLATFORM: PLATFORM,
|
||||
CONF_HOST: '127.0.0.1',
|
||||
CONF_NAME: entity_name,
|
||||
CONF_TOKEN: '12345678901234567890123456789012'}})
|
||||
|
||||
assert 'Initializing with host 127.0.0.1 (token 12345...)' in caplog.text
|
||||
assert str(mock_mirobo_errors.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert 'ERROR' in caplog.text
|
||||
assert 'Got OSError while fetching the state' in caplog.text
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_off):
|
||||
"""Test vacuum supported features."""
|
||||
entity_name = 'test_vacuum_cleaner_1'
|
||||
entity_id = '{}.{}'.format(DOMAIN, entity_name)
|
||||
|
||||
yield from async_setup_component(
|
||||
@ -63,7 +114,7 @@ def test_xiaomi_vacuum(hass, caplog, mock_mirobo):
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 1023
|
||||
assert state.attributes.get(ATTR_DO_NOT_DISTURB) == STATE_ON
|
||||
assert state.attributes.get(ATTR_ERROR) is None
|
||||
assert state.attributes.get(ATTR_ERROR) == 'Error message'
|
||||
assert (state.attributes.get(ATTR_BATTERY_ICON)
|
||||
== 'mdi:battery-charging-80')
|
||||
assert state.attributes.get(ATTR_CLEANING_TIME) == '2:35:34'
|
||||
@ -75,80 +126,137 @@ def test_xiaomi_vacuum(hass, caplog, mock_mirobo):
|
||||
# Call services
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_TURN_ON, blocking=True)
|
||||
assert str(mock_mirobo.mock_calls[-2]) == 'call.Vacuum().start()'
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().start()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_TURN_OFF, blocking=True)
|
||||
assert str(mock_mirobo.mock_calls[-2]) == 'call.Vacuum().home()'
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().home()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_TOGGLE, blocking=True)
|
||||
assert str(mock_mirobo.mock_calls[-2]) == 'call.Vacuum().start()'
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().start()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_STOP, blocking=True)
|
||||
assert str(mock_mirobo.mock_calls[-2]) == 'call.Vacuum().stop()'
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().stop()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_START_PAUSE, blocking=True)
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().start()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_RETURN_TO_BASE, blocking=True)
|
||||
assert str(mock_mirobo.mock_calls[-2]) == 'call.Vacuum().home()'
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().home()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_LOCATE, blocking=True)
|
||||
assert str(mock_mirobo.mock_calls[-2]) == 'call.Vacuum().find()'
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().find()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
# Set speed service:
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": 60}, blocking=True)
|
||||
assert (str(mock_mirobo.mock_calls[-2])
|
||||
assert (str(mock_mirobo_is_off.mock_calls[-2])
|
||||
== 'call.Vacuum().set_fan_speed(60)')
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": "turbo"}, blocking=True)
|
||||
assert (str(mock_mirobo_is_off.mock_calls[-2])
|
||||
== 'call.Vacuum().set_fan_speed(77)')
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
assert 'ERROR' not in caplog.text
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": "invent"}, blocking=True)
|
||||
assert 'ERROR' in caplog.text
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_SEND_COMMAND,
|
||||
{"command": "raw"}, blocking=True)
|
||||
assert (str(mock_mirobo.mock_calls[-2])
|
||||
assert (str(mock_mirobo_is_off.mock_calls[-2])
|
||||
== "call.Vacuum().raw_command('raw', None)")
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_SEND_COMMAND,
|
||||
{"command": "raw", "params": {"k1": 2}}, blocking=True)
|
||||
assert (str(mock_mirobo.mock_calls[-2])
|
||||
assert (str(mock_mirobo_is_off.mock_calls[-2])
|
||||
== "call.Vacuum().raw_command('raw', {'k1': 2})")
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_xiaomi_vacuum_specific_services(hass, caplog, mock_mirobo_is_on):
|
||||
"""Test vacuum supported features."""
|
||||
entity_name = 'test_vacuum_cleaner_2'
|
||||
entity_id = '{}.{}'.format(DOMAIN, entity_name)
|
||||
|
||||
yield from async_setup_component(
|
||||
hass, DOMAIN,
|
||||
{DOMAIN: {CONF_PLATFORM: PLATFORM,
|
||||
CONF_HOST: '192.168.1.100',
|
||||
CONF_NAME: entity_name,
|
||||
CONF_TOKEN: '12345678901234567890123456789012'}})
|
||||
|
||||
assert 'Initializing with host 192.168.1.100 (token 12345' in caplog.text
|
||||
|
||||
# Check state attributes
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 1023
|
||||
assert state.attributes.get(ATTR_DO_NOT_DISTURB) == STATE_OFF
|
||||
assert state.attributes.get(ATTR_ERROR) is None
|
||||
assert (state.attributes.get(ATTR_BATTERY_ICON)
|
||||
== 'mdi:battery-30')
|
||||
assert state.attributes.get(ATTR_CLEANING_TIME) == '2:55:34'
|
||||
assert state.attributes.get(ATTR_CLEANED_AREA) == 133.43
|
||||
assert state.attributes.get(ATTR_FAN_SPEED) == 99
|
||||
assert (state.attributes.get(ATTR_FAN_SPEED_LIST)
|
||||
== ['Quiet', 'Balanced', 'Turbo', 'Max'])
|
||||
|
||||
# Check setting pause
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_START_REMOTE_CONTROL, {}, blocking=True)
|
||||
assert (str(mock_mirobo.mock_calls[-2])
|
||||
DOMAIN, SERVICE_START_PAUSE, blocking=True)
|
||||
assert str(mock_mirobo_is_on.mock_calls[-2]) == 'call.Vacuum().pause()'
|
||||
assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
# Xiaomi vacuum specific services:
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_START_REMOTE_CONTROL,
|
||||
{ATTR_ENTITY_ID: entity_id}, blocking=True)
|
||||
assert (str(mock_mirobo_is_on.mock_calls[-2])
|
||||
== "call.Vacuum().manual_start()")
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_MOVE_REMOTE_CONTROL,
|
||||
{"duration": 1000, "rotation": -40, "velocity": -0.1}, blocking=True)
|
||||
assert 'call.Vacuum().manual_control(' in str(mock_mirobo.mock_calls[-2])
|
||||
assert 'duration=1000' in str(mock_mirobo.mock_calls[-2])
|
||||
assert 'rotation=-40' in str(mock_mirobo.mock_calls[-2])
|
||||
assert 'velocity=-0.1' in str(mock_mirobo.mock_calls[-2])
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert ('call.Vacuum().manual_control('
|
||||
in str(mock_mirobo_is_on.mock_calls[-2]))
|
||||
assert 'duration=1000' in str(mock_mirobo_is_on.mock_calls[-2])
|
||||
assert 'rotation=-40' in str(mock_mirobo_is_on.mock_calls[-2])
|
||||
assert 'velocity=-0.1' in str(mock_mirobo_is_on.mock_calls[-2])
|
||||
assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_STOP_REMOTE_CONTROL, {}, blocking=True)
|
||||
assert (str(mock_mirobo.mock_calls[-2])
|
||||
assert (str(mock_mirobo_is_on.mock_calls[-2])
|
||||
== "call.Vacuum().manual_stop()")
|
||||
assert str(mock_mirobo.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
||||
yield from hass.services.async_call(
|
||||
DOMAIN, SERVICE_MOVE_REMOTE_CONTROL_STEP,
|
||||
{"duration": 2000, "rotation": 120, "velocity": 0.1}, blocking=True)
|
||||
assert ('call.Vacuum().manual_control_once('
|
||||
in str(mock_mirobo.mock_calls[-2]))
|
||||
assert 'duration=2000' in str(mock_mirobo.mock_calls[-2])
|
||||
assert 'rotation=120' in str(mock_mirobo.mock_calls[-2])
|
||||
assert 'velocity=0.1' in str(mock_mirobo.mock_calls[-2])
|
||||
in str(mock_mirobo_is_on.mock_calls[-2]))
|
||||
assert 'duration=2000' in str(mock_mirobo_is_on.mock_calls[-2])
|
||||
assert 'rotation=120' in str(mock_mirobo_is_on.mock_calls[-2])
|
||||
assert 'velocity=0.1' in str(mock_mirobo_is_on.mock_calls[-2])
|
||||
assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()'
|
||||
|
Loading…
x
Reference in New Issue
Block a user