Skip to content

Commit

Permalink
Vacuum component: start_pause to individual start and pause commands. (
Browse files Browse the repository at this point in the history
…#15751)

* Add start and pause to StateVacuumDevice, move start_pause to VacuumDevice

* Updated demo vacuum and tests

* Add a few more tests
  • Loading branch information
cnrd authored and awarecan committed Aug 3, 2018
1 parent 59f8a73 commit b63312f
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 25 deletions.
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):
"""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)
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

0 comments on commit b63312f

Please sign in to comment.