Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 53 additions & 12 deletions homeassistant/components/vacuum/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
SERVICE_SEND_COMMAND = 'send_command'
SERVICE_SET_FAN_SPEED = 'set_fan_speed'
SERVICE_START_PAUSE = 'start_pause'
SERVICE_START = 'start'
SERVICE_PAUSE = 'pause'
SERVICE_STOP = 'stop'

VACUUM_SERVICE_SCHEMA = vol.Schema({
Expand All @@ -65,6 +67,8 @@
SERVICE_TURN_OFF: {'method': 'async_turn_off'},
SERVICE_TOGGLE: {'method': 'async_toggle'},
SERVICE_START_PAUSE: {'method': 'async_start_pause'},
SERVICE_START: {'method': 'async_start'},
SERVICE_PAUSE: {'method': 'async_pause'},
SERVICE_RETURN_TO_BASE: {'method': 'async_return_to_base'},
SERVICE_CLEAN_SPOT: {'method': 'async_clean_spot'},
SERVICE_LOCATE: {'method': 'async_locate'},
Expand Down Expand Up @@ -97,6 +101,7 @@
SUPPORT_CLEAN_SPOT = 1024
SUPPORT_MAP = 2048
SUPPORT_STATE = 4096
SUPPORT_START = 8192


@bind_hass
Expand Down Expand Up @@ -155,6 +160,20 @@ def start_pause(hass, entity_id=None):
hass.services.call(DOMAIN, SERVICE_START_PAUSE, data)


@bind_hass
def start(hass, entity_id=None):
"""Tell all or specified vacuum to start or resume the current task."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else None
hass.services.call(DOMAIN, SERVICE_START, data)


@bind_hass
def pause(hass, entity_id=None):
"""Tell all or the specified vacuum to pause the current task."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else None
hass.services.call(DOMAIN, SERVICE_PAUSE, data)


@bind_hass
def stop(hass, entity_id=None):
"""Stop all or specified vacuum."""
Expand Down Expand Up @@ -242,18 +261,6 @@ def fan_speed_list(self):
"""Get the list of available fan speed steps of the vacuum cleaner."""
raise NotImplementedError()

def start_pause(self, **kwargs):
"""Start, pause or resume the cleaning task."""
raise NotImplementedError()

async def async_start_pause(self, **kwargs):
"""Start, pause or resume the cleaning task.

This method must be run in the event loop.
"""
await self.hass.async_add_executor_job(
partial(self.start_pause, **kwargs))

def stop(self, **kwargs):
"""Stop the vacuum cleaner."""
raise NotImplementedError()
Expand Down Expand Up @@ -384,6 +391,18 @@ async def async_turn_off(self, **kwargs):
await self.hass.async_add_executor_job(
partial(self.turn_off, **kwargs))

def start_pause(self, **kwargs):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any tests for this method and service now that we've moved it from base to legacy vaccum entity class.

"""Start, pause or resume the cleaning task."""
raise NotImplementedError()

async def async_start_pause(self, **kwargs):
"""Start, pause or resume the cleaning task.

This method must be run in the event loop.
"""
await self.hass.async_add_executor_job(
partial(self.start_pause, **kwargs))


class StateVacuumDevice(_BaseVacuum):
"""Representation of a vacuum cleaner robot that supports states."""
Expand Down Expand Up @@ -415,3 +434,25 @@ def state_attributes(self):
data[ATTR_FAN_SPEED_LIST] = self.fan_speed_list

return data

def start(self):
"""Start or resume the cleaning task."""
raise NotImplementedError()

async def async_start(self):
"""Start or resume the cleaning task.

This method must be run in the event loop.
"""
await self.hass.async_add_executor_job(self.start)

def pause(self):
"""Pause the cleaning task."""
raise NotImplementedError()

async def async_pause(self):
"""Pause the cleaning task.

This method must be run in the event loop.
"""
await self.hass.async_add_executor_job(self.pause)
27 changes: 17 additions & 10 deletions homeassistant/components/vacuum/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
ATTR_CLEANED_AREA, SUPPORT_BATTERY, SUPPORT_CLEAN_SPOT,
SUPPORT_FAN_SPEED, SUPPORT_LOCATE, SUPPORT_PAUSE, SUPPORT_RETURN_HOME,
SUPPORT_SEND_COMMAND, SUPPORT_STATUS, SUPPORT_STOP, SUPPORT_TURN_OFF,
SUPPORT_TURN_ON, SUPPORT_STATE, STATE_CLEANING, STATE_DOCKED,
STATE_IDLE, STATE_PAUSED, STATE_RETURNING, VacuumDevice,
SUPPORT_TURN_ON, SUPPORT_STATE, SUPPORT_START, STATE_CLEANING,
STATE_DOCKED, STATE_IDLE, STATE_PAUSED, STATE_RETURNING, VacuumDevice,
StateVacuumDevice)

_LOGGER = logging.getLogger(__name__)
Expand All @@ -32,7 +32,7 @@

SUPPORT_STATE_SERVICES = SUPPORT_STATE | SUPPORT_PAUSE | SUPPORT_STOP | \
SUPPORT_RETURN_HOME | SUPPORT_FAN_SPEED | \
SUPPORT_BATTERY | SUPPORT_CLEAN_SPOT
SUPPORT_BATTERY | SUPPORT_CLEAN_SPOT | SUPPORT_START

FAN_SPEEDS = ['min', 'medium', 'high', 'max']
DEMO_VACUUM_COMPLETE = '0_Ground_floor'
Expand Down Expand Up @@ -274,18 +274,25 @@ def device_state_attributes(self):
"""Return device state attributes."""
return {ATTR_CLEANED_AREA: round(self._cleaned_area, 2)}

def start_pause(self, **kwargs):
"""Start, pause or resume the cleaning task."""
if self.supported_features & SUPPORT_PAUSE == 0:
def start(self):
"""Start or resume the cleaning task."""
if self.supported_features & SUPPORT_START == 0:
return

if self._state == STATE_CLEANING:
self._state = STATE_PAUSED
else:
if self._state != STATE_CLEANING:
self._state = STATE_CLEANING
self._cleaned_area += 1.32
self._battery_level -= 1
self.schedule_update_ha_state()
self.schedule_update_ha_state()

def pause(self):
"""Pause the cleaning task."""
if self.supported_features & SUPPORT_PAUSE == 0:
return

if self._state == STATE_CLEANING:
self._state = STATE_PAUSED
self.schedule_update_ha_state()

def stop(self, **kwargs):
"""Stop the cleaning task, do not return to dock."""
Expand Down
14 changes: 14 additions & 0 deletions homeassistant/components/vacuum/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ start_pause:
description: Name of the vacuum entity.
example: 'vacuum.xiaomi_vacuum_cleaner'

start:
description: Start or resume the cleaning task.
fields:
entity_id:
description: Name of the vacuum entity.
example: 'vacuum.xiaomi_vacuum_cleaner'

pause:
description: Pause the cleaning task.
fields:
entity_id:
description: Name of the vacuum entity.
example: 'vacuum.xiaomi_vacuum_cleaner'

return_to_base:
description: Tell the vacuum cleaner to return to its dock.
fields:
Expand Down
23 changes: 20 additions & 3 deletions tests/components/vacuum/test_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_supported_features(self):
self.assertEqual(STATE_OFF, state.state)

state = self.hass.states.get(ENTITY_VACUUM_STATE)
self.assertEqual(5244, state.attributes.get(ATTR_SUPPORTED_FEATURES))
self.assertEqual(13436, state.attributes.get(ATTR_SUPPORTED_FEATURES))
self.assertEqual(STATE_DOCKED, state.state)
self.assertEqual(100, state.attributes.get(ATTR_BATTERY_LEVEL))
self.assertEqual("medium", state.attributes.get(ATTR_FAN_SPEED))
Expand Down Expand Up @@ -158,12 +158,12 @@ def test_methods(self):
self.assertIn("spot", state.attributes.get(ATTR_STATUS))
self.assertEqual(STATE_ON, state.state)

vacuum.start_pause(self.hass, ENTITY_VACUUM_STATE)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should have commented here instead...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vacuum.start(self.hass, ENTITY_VACUUM_STATE)
self.hass.block_till_done()
state = self.hass.states.get(ENTITY_VACUUM_STATE)
self.assertEqual(STATE_CLEANING, state.state)

vacuum.start_pause(self.hass, ENTITY_VACUUM_STATE)
vacuum.pause(self.hass, ENTITY_VACUUM_STATE)
self.hass.block_till_done()
state = self.hass.states.get(ENTITY_VACUUM_STATE)
self.assertEqual(STATE_PAUSED, state.state)
Expand Down Expand Up @@ -247,6 +247,23 @@ def test_unsupported_methods(self):
self.assertNotIn("spot", state.attributes.get(ATTR_STATUS))
self.assertEqual(STATE_OFF, state.state)

# VacuumDevice should not support start and pause methods.
self.hass.states.set(ENTITY_VACUUM_COMPLETE, STATE_ON)
self.hass.block_till_done()
self.assertTrue(vacuum.is_on(self.hass, ENTITY_VACUUM_COMPLETE))

vacuum.pause(self.hass, ENTITY_VACUUM_COMPLETE)
self.hass.block_till_done()
self.assertTrue(vacuum.is_on(self.hass, ENTITY_VACUUM_COMPLETE))

self.hass.states.set(ENTITY_VACUUM_COMPLETE, STATE_OFF)
self.hass.block_till_done()
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_COMPLETE))

vacuum.start(self.hass, ENTITY_VACUUM_COMPLETE)
self.hass.block_till_done()
self.assertFalse(vacuum.is_on(self.hass, ENTITY_VACUUM_COMPLETE))

# StateVacuumDevice does not support on/off
vacuum.turn_on(self.hass, entity_id=ENTITY_VACUUM_STATE)
self.hass.block_till_done()
Expand Down