Xiaomi Vacuum: remove deprecated calls (#10839)

* vacuum.xiaomi_miio: read dnd status properly instead of using imprecise dnd flag from vacuum_state

* vacuum.xiaomi_miio: use miio package instead of mirobo

* check only that wanted calls have taken place, ignore order of calls

* Fix linting issues

* Remove empty line after docstring
This commit is contained in:
Teemu R 2017-12-01 12:28:59 +01:00 committed by Pascal Vizeli
parent 493de295ac
commit 7b452208b6
2 changed files with 101 additions and 135 deletions

View File

@ -48,6 +48,8 @@ FAN_SPEEDS = {
ATTR_CLEANING_TIME = 'cleaning_time' ATTR_CLEANING_TIME = 'cleaning_time'
ATTR_DO_NOT_DISTURB = 'do_not_disturb' ATTR_DO_NOT_DISTURB = 'do_not_disturb'
ATTR_DO_NOT_DISTURB_START = 'do_not_disturb_start'
ATTR_DO_NOT_DISTURB_END = 'do_not_disturb_end'
ATTR_MAIN_BRUSH_LEFT = 'main_brush_left' ATTR_MAIN_BRUSH_LEFT = 'main_brush_left'
ATTR_SIDE_BRUSH_LEFT = 'side_brush_left' ATTR_SIDE_BRUSH_LEFT = 'side_brush_left'
ATTR_FILTER_LEFT = 'filter_left' ATTR_FILTER_LEFT = 'filter_left'
@ -87,7 +89,7 @@ SUPPORT_XIAOMI = SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PAUSE | \
@asyncio.coroutine @asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the Xiaomi vacuum cleaner robot platform.""" """Set up the Xiaomi vacuum cleaner robot platform."""
from mirobo import Vacuum from miio import Vacuum
if PLATFORM not in hass.data: if PLATFORM not in hass.data:
hass.data[PLATFORM] = {} hass.data[PLATFORM] = {}
@ -155,6 +157,7 @@ class MiroboVacuum(VacuumDevice):
self.consumable_state = None self.consumable_state = None
self.clean_history = None self.clean_history = None
self.dnd_state = None
@property @property
def name(self): def name(self):
@ -200,7 +203,9 @@ class MiroboVacuum(VacuumDevice):
if self.vacuum_state is not None: if self.vacuum_state is not None:
attrs.update({ attrs.update({
ATTR_DO_NOT_DISTURB: ATTR_DO_NOT_DISTURB:
STATE_ON if self.vacuum_state.dnd else STATE_OFF, STATE_ON if self.dnd_state.enabled else STATE_OFF,
ATTR_DO_NOT_DISTURB_START: str(self.dnd_state.start),
ATTR_DO_NOT_DISTURB_END: str(self.dnd_state.end),
# Not working --> 'Cleaning mode': # Not working --> 'Cleaning mode':
# STATE_ON if self.vacuum_state.in_cleaning else STATE_OFF, # STATE_ON if self.vacuum_state.in_cleaning else STATE_OFF,
ATTR_CLEANING_TIME: int( ATTR_CLEANING_TIME: int(
@ -223,7 +228,6 @@ class MiroboVacuum(VacuumDevice):
/ 3600)}) / 3600)})
if self.vacuum_state.got_error: if self.vacuum_state.got_error:
attrs[ATTR_ERROR] = self.vacuum_state.error attrs[ATTR_ERROR] = self.vacuum_state.error
return attrs return attrs
@property @property
@ -244,11 +248,11 @@ class MiroboVacuum(VacuumDevice):
@asyncio.coroutine @asyncio.coroutine
def _try_command(self, mask_error, func, *args, **kwargs): def _try_command(self, mask_error, func, *args, **kwargs):
"""Call a vacuum command handling error messages.""" """Call a vacuum command handling error messages."""
from mirobo import DeviceException, VacuumException from miio import DeviceException
try: try:
yield from self.hass.async_add_job(partial(func, *args, **kwargs)) yield from self.hass.async_add_job(partial(func, *args, **kwargs))
return True return True
except (DeviceException, VacuumException) as exc: except DeviceException as exc:
_LOGGER.error(mask_error, exc) _LOGGER.error(mask_error, exc)
return False return False
@ -365,12 +369,15 @@ class MiroboVacuum(VacuumDevice):
def update(self): def update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
from mirobo import DeviceException from miio import DeviceException
try: try:
state = self._vacuum.status() state = self._vacuum.status()
self.vacuum_state = state self.vacuum_state = state
self.consumable_state = self._vacuum.consumable_status() self.consumable_state = self._vacuum.consumable_status()
self.clean_history = self._vacuum.clean_history() self.clean_history = self._vacuum.clean_history()
self.dnd_state = self._vacuum.dnd_status()
self._is_on = state.is_on self._is_on = state.is_on
self._available = True self._available = True
except OSError as exc: except OSError as exc:

View File

@ -1,6 +1,6 @@
"""The tests for the Xiaomi vacuum platform.""" """The tests for the Xiaomi vacuum platform."""
import asyncio import asyncio
from datetime import timedelta from datetime import timedelta, time
from unittest import mock from unittest import mock
import pytest import pytest
@ -12,7 +12,8 @@ from homeassistant.components.vacuum import (
SERVICE_SEND_COMMAND, SERVICE_SET_FAN_SPEED, SERVICE_START_PAUSE, SERVICE_SEND_COMMAND, SERVICE_SET_FAN_SPEED, SERVICE_START_PAUSE,
SERVICE_STOP, SERVICE_TOGGLE, SERVICE_TURN_OFF, SERVICE_TURN_ON) SERVICE_STOP, SERVICE_TOGGLE, SERVICE_TURN_OFF, SERVICE_TURN_ON)
from homeassistant.components.vacuum.xiaomi_miio import ( from homeassistant.components.vacuum.xiaomi_miio import (
ATTR_CLEANED_AREA, ATTR_CLEANING_TIME, ATTR_DO_NOT_DISTURB, ATTR_ERROR, ATTR_CLEANED_AREA, ATTR_CLEANING_TIME, ATTR_DO_NOT_DISTURB,
ATTR_DO_NOT_DISTURB_START, ATTR_DO_NOT_DISTURB_END, ATTR_ERROR,
ATTR_MAIN_BRUSH_LEFT, ATTR_SIDE_BRUSH_LEFT, ATTR_FILTER_LEFT, ATTR_MAIN_BRUSH_LEFT, ATTR_SIDE_BRUSH_LEFT, ATTR_FILTER_LEFT,
ATTR_CLEANING_COUNT, ATTR_CLEANED_TOTAL_AREA, ATTR_CLEANING_TOTAL_TIME, ATTR_CLEANING_COUNT, ATTR_CLEANED_TOTAL_AREA, ATTR_CLEANING_TOTAL_TIME,
CONF_HOST, CONF_NAME, CONF_TOKEN, PLATFORM, CONF_HOST, CONF_NAME, CONF_TOKEN, PLATFORM,
@ -23,6 +24,12 @@ from homeassistant.const import (
STATE_ON) STATE_ON)
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
# calls made when device status is requested
status_calls = [mock.call.Vacuum().status(),
mock.call.Vacuum().consumable_status(),
mock.call.Vacuum().clean_history(),
mock.call.Vacuum().dnd_status()]
@pytest.fixture @pytest.fixture
def mock_mirobo_is_off(): def mock_mirobo_is_off():
@ -33,7 +40,6 @@ def mock_mirobo_is_off():
mock_vacuum.Vacuum().status().fanspeed = 38 mock_vacuum.Vacuum().status().fanspeed = 38
mock_vacuum.Vacuum().status().got_error = True mock_vacuum.Vacuum().status().got_error = True
mock_vacuum.Vacuum().status().error = 'Error message' mock_vacuum.Vacuum().status().error = 'Error message'
mock_vacuum.Vacuum().status().dnd = True
mock_vacuum.Vacuum().status().battery = 82 mock_vacuum.Vacuum().status().battery = 82
mock_vacuum.Vacuum().status().clean_area = 123.43218 mock_vacuum.Vacuum().status().clean_area = 123.43218
mock_vacuum.Vacuum().status().clean_time = timedelta( mock_vacuum.Vacuum().status().clean_time = timedelta(
@ -49,9 +55,12 @@ def mock_mirobo_is_off():
mock_vacuum.Vacuum().clean_history().total_duration = timedelta( mock_vacuum.Vacuum().clean_history().total_duration = timedelta(
hours=11, minutes=35, seconds=34) hours=11, minutes=35, seconds=34)
mock_vacuum.Vacuum().status().state = 'Test Xiaomi Charging' mock_vacuum.Vacuum().status().state = 'Test Xiaomi Charging'
mock_vacuum.Vacuum().dnd_status().enabled = True
mock_vacuum.Vacuum().dnd_status().start = time(hour=22, minute=0)
mock_vacuum.Vacuum().dnd_status().end = time(hour=6, minute=0)
with mock.patch.dict('sys.modules', { with mock.patch.dict('sys.modules', {
'mirobo': mock_vacuum, 'miio': mock_vacuum,
}): }):
yield mock_vacuum yield mock_vacuum
@ -64,7 +73,6 @@ def mock_mirobo_is_on():
mock_vacuum.Vacuum().status().is_on = True mock_vacuum.Vacuum().status().is_on = True
mock_vacuum.Vacuum().status().fanspeed = 99 mock_vacuum.Vacuum().status().fanspeed = 99
mock_vacuum.Vacuum().status().got_error = False mock_vacuum.Vacuum().status().got_error = False
mock_vacuum.Vacuum().status().dnd = False
mock_vacuum.Vacuum().status().battery = 32 mock_vacuum.Vacuum().status().battery = 32
mock_vacuum.Vacuum().status().clean_area = 133.43218 mock_vacuum.Vacuum().status().clean_area = 133.43218
mock_vacuum.Vacuum().status().clean_time = timedelta( mock_vacuum.Vacuum().status().clean_time = timedelta(
@ -80,9 +88,10 @@ def mock_mirobo_is_on():
mock_vacuum.Vacuum().clean_history().total_duration = timedelta( mock_vacuum.Vacuum().clean_history().total_duration = timedelta(
hours=11, minutes=15, seconds=34) hours=11, minutes=15, seconds=34)
mock_vacuum.Vacuum().status().state = 'Test Xiaomi Cleaning' mock_vacuum.Vacuum().status().state = 'Test Xiaomi Cleaning'
mock_vacuum.Vacuum().dnd_status().enabled = False
with mock.patch.dict('sys.modules', { with mock.patch.dict('sys.modules', {
'mirobo': mock_vacuum, 'miio': mock_vacuum,
}): }):
yield mock_vacuum yield mock_vacuum
@ -93,7 +102,7 @@ def mock_mirobo_errors():
mock_vacuum = mock.MagicMock() mock_vacuum = mock.MagicMock()
mock_vacuum.Vacuum().status.side_effect = OSError() mock_vacuum.Vacuum().status.side_effect = OSError()
with mock.patch.dict('sys.modules', { with mock.patch.dict('sys.modules', {
'mirobo': mock_vacuum, 'miio': mock_vacuum,
}): }):
yield mock_vacuum yield mock_vacuum
@ -136,6 +145,8 @@ def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_off):
assert state.state == STATE_OFF assert state.state == STATE_OFF
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 2047 assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 2047
assert state.attributes.get(ATTR_DO_NOT_DISTURB) == STATE_ON assert state.attributes.get(ATTR_DO_NOT_DISTURB) == STATE_ON
assert state.attributes.get(ATTR_DO_NOT_DISTURB_START) == '22:00:00'
assert state.attributes.get(ATTR_DO_NOT_DISTURB_END) == '06:00:00'
assert state.attributes.get(ATTR_ERROR) == 'Error message' assert state.attributes.get(ATTR_ERROR) == 'Error message'
assert (state.attributes.get(ATTR_BATTERY_ICON) assert (state.attributes.get(ATTR_BATTERY_ICON)
== 'mdi:battery-charging-80') == 'mdi:battery-charging-80')
@ -154,96 +165,75 @@ def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_off):
# Call services # Call services
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_TURN_ON, blocking=True) DOMAIN, SERVICE_TURN_ON, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().start()'
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' mock_mirobo_is_off.assert_has_calls(
assert (str(mock_mirobo_is_off.mock_calls[-2]) [mock.call.Vacuum.start()], any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-1]) mock_mirobo_is_off.reset_mock()
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_TURN_OFF, blocking=True) DOMAIN, SERVICE_TURN_OFF, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().home()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().home()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_TOGGLE, blocking=True) DOMAIN, SERVICE_TOGGLE, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().start()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().start()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_STOP, blocking=True) DOMAIN, SERVICE_STOP, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().stop()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().stop()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_START_PAUSE, blocking=True) DOMAIN, SERVICE_START_PAUSE, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().start()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().pause()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_RETURN_TO_BASE, blocking=True) DOMAIN, SERVICE_RETURN_TO_BASE, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().home()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().home()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_LOCATE, blocking=True) DOMAIN, SERVICE_LOCATE, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().find()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().find()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_CLEAN_SPOT, {}, blocking=True) DOMAIN, SERVICE_CLEAN_SPOT, {}, blocking=True)
assert str(mock_mirobo_is_off.mock_calls[-4]) == 'call.Vacuum().spot()' mock_mirobo_is_off.assert_has_calls(
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' [mock.call.Vacuum().spot()], any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
== 'call.Vacuum().consumable_status()') mock_mirobo_is_off.reset_mock()
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
# Set speed service: # Set speed service:
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": 60}, blocking=True) DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": 60}, blocking=True)
assert (str(mock_mirobo_is_off.mock_calls[-4]) mock_mirobo_is_off.assert_has_calls(
== 'call.Vacuum().set_fan_speed(60)') [mock.call.Vacuum().set_fan_speed(60)], any_order=True)
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.reset_mock()
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": "turbo"}, blocking=True) DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": "turbo"}, blocking=True)
assert (str(mock_mirobo_is_off.mock_calls[-4]) mock_mirobo_is_off.assert_has_calls(
== 'call.Vacuum().set_fan_speed(77)') [mock.call.Vacuum().set_fan_speed(77)], any_order=True)
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.reset_mock()
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
assert 'ERROR' not in caplog.text assert 'ERROR' not in caplog.text
yield from hass.services.async_call( yield from hass.services.async_call(
@ -253,24 +243,18 @@ def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_off):
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_SEND_COMMAND, DOMAIN, SERVICE_SEND_COMMAND,
{"command": "raw"}, blocking=True) {"command": "raw"}, blocking=True)
assert (str(mock_mirobo_is_off.mock_calls[-4]) mock_mirobo_is_off.assert_has_calls(
== "call.Vacuum().raw_command('raw', None)") [mock.call.Vacuum().raw_command('raw', None)], any_order=True)
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.reset_mock()
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_SEND_COMMAND, DOMAIN, SERVICE_SEND_COMMAND,
{"command": "raw", "params": {"k1": 2}}, blocking=True) {"command": "raw", "params": {"k1": 2}}, blocking=True)
assert (str(mock_mirobo_is_off.mock_calls[-4]) mock_mirobo_is_off.assert_has_calls(
== "call.Vacuum().raw_command('raw', {'k1': 2})") [mock.call.Vacuum().raw_command('raw', {'k1': 2})], any_order=True)
assert str(mock_mirobo_is_off.mock_calls[-3]) == 'call.Vacuum().status()' mock_mirobo_is_off.assert_has_calls(status_calls, any_order=True)
assert (str(mock_mirobo_is_off.mock_calls[-2]) mock_mirobo_is_off.reset_mock()
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_off.mock_calls[-1])
== 'call.Vacuum().clean_history()')
@asyncio.coroutine @asyncio.coroutine
@ -308,62 +292,37 @@ def test_xiaomi_specific_services(hass, caplog, mock_mirobo_is_on):
assert state.attributes.get(ATTR_CLEANED_TOTAL_AREA) == 323 assert state.attributes.get(ATTR_CLEANED_TOTAL_AREA) == 323
assert state.attributes.get(ATTR_CLEANING_TOTAL_TIME) == 675 assert state.attributes.get(ATTR_CLEANING_TOTAL_TIME) == 675
# Check setting pause
yield from hass.services.async_call(
DOMAIN, SERVICE_START_PAUSE, blocking=True)
assert str(mock_mirobo_is_on.mock_calls[-4]) == 'call.Vacuum().pause()'
assert str(mock_mirobo_is_on.mock_calls[-3]) == 'call.Vacuum().status()'
assert (str(mock_mirobo_is_on.mock_calls[-2])
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_on.mock_calls[-1])
== 'call.Vacuum().clean_history()')
# Xiaomi vacuum specific services: # Xiaomi vacuum specific services:
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_START_REMOTE_CONTROL, DOMAIN, SERVICE_START_REMOTE_CONTROL,
{ATTR_ENTITY_ID: entity_id}, blocking=True) {ATTR_ENTITY_ID: entity_id}, blocking=True)
assert (str(mock_mirobo_is_on.mock_calls[-4])
== "call.Vacuum().manual_start()")
assert str(mock_mirobo_is_on.mock_calls[-3]) == 'call.Vacuum().status()'
assert (str(mock_mirobo_is_on.mock_calls[-2])
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_on.mock_calls[-1])
== 'call.Vacuum().clean_history()')
mock_mirobo_is_on.assert_has_calls(
[mock.call.Vacuum().manual_start()], any_order=True)
mock_mirobo_is_on.assert_has_calls(status_calls, any_order=True)
mock_mirobo_is_on.reset_mock()
control = {"duration": 1000, "rotation": -40, "velocity": -0.1}
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_MOVE_REMOTE_CONTROL, DOMAIN, SERVICE_MOVE_REMOTE_CONTROL,
{"duration": 1000, "rotation": -40, "velocity": -0.1}, blocking=True) control, blocking=True)
assert ('call.Vacuum().manual_control(' mock_mirobo_is_on.assert_has_calls(
in str(mock_mirobo_is_on.mock_calls[-4])) [mock.call.Vacuum().manual_control(control)], any_order=True)
assert 'duration=1000' in str(mock_mirobo_is_on.mock_calls[-4]) mock_mirobo_is_on.assert_has_calls(status_calls, any_order=True)
assert 'rotation=-40' in str(mock_mirobo_is_on.mock_calls[-4]) mock_mirobo_is_on.reset_mock()
assert 'velocity=-0.1' in str(mock_mirobo_is_on.mock_calls[-4])
assert str(mock_mirobo_is_on.mock_calls[-3]) == 'call.Vacuum().status()'
assert (str(mock_mirobo_is_on.mock_calls[-2])
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_on.mock_calls[-1])
== 'call.Vacuum().clean_history()')
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_STOP_REMOTE_CONTROL, {}, blocking=True) DOMAIN, SERVICE_STOP_REMOTE_CONTROL, {}, blocking=True)
assert (str(mock_mirobo_is_on.mock_calls[-4]) mock_mirobo_is_on.assert_has_calls(
== "call.Vacuum().manual_stop()") [mock.call.Vacuum().manual_stop()], any_order=True)
assert str(mock_mirobo_is_on.mock_calls[-3]) == 'call.Vacuum().status()' mock_mirobo_is_on.assert_has_calls(status_calls, any_order=True)
assert (str(mock_mirobo_is_on.mock_calls[-2]) mock_mirobo_is_on.reset_mock()
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_on.mock_calls[-1])
== 'call.Vacuum().clean_history()')
control_once = {"duration": 2000, "rotation": 120, "velocity": 0.1}
yield from hass.services.async_call( yield from hass.services.async_call(
DOMAIN, SERVICE_MOVE_REMOTE_CONTROL_STEP, DOMAIN, SERVICE_MOVE_REMOTE_CONTROL_STEP,
{"duration": 2000, "rotation": 120, "velocity": 0.1}, blocking=True) control_once, blocking=True)
assert ('call.Vacuum().manual_control_once(' mock_mirobo_is_on.assert_has_calls(
in str(mock_mirobo_is_on.mock_calls[-4])) [mock.call.Vacuum().manual_control_once(control_once)], any_order=True)
assert 'duration=2000' in str(mock_mirobo_is_on.mock_calls[-4]) mock_mirobo_is_on.assert_has_calls(status_calls, any_order=True)
assert 'rotation=120' in str(mock_mirobo_is_on.mock_calls[-4]) mock_mirobo_is_on.reset_mock()
assert 'velocity=0.1' in str(mock_mirobo_is_on.mock_calls[-4])
assert str(mock_mirobo_is_on.mock_calls[-3]) == 'call.Vacuum().status()'
assert (str(mock_mirobo_is_on.mock_calls[-2])
== 'call.Vacuum().consumable_status()')
assert (str(mock_mirobo_is_on.mock_calls[-1])
== 'call.Vacuum().clean_history()')