mirror of
https://github.com/home-assistant/core
synced 2024-09-18 19:55:20 +02:00
Vacuum component: start_pause to individual start and pause commands. (#15751)
* Add start and pause to StateVacuumDevice, move start_pause to VacuumDevice * Updated demo vacuum and tests * Add a few more tests
This commit is contained in:
parent
59f8a73676
commit
b63312ff2e
@ -45,6 +45,8 @@ SERVICE_RETURN_TO_BASE = 'return_to_base'
|
|||||||
SERVICE_SEND_COMMAND = 'send_command'
|
SERVICE_SEND_COMMAND = 'send_command'
|
||||||
SERVICE_SET_FAN_SPEED = 'set_fan_speed'
|
SERVICE_SET_FAN_SPEED = 'set_fan_speed'
|
||||||
SERVICE_START_PAUSE = 'start_pause'
|
SERVICE_START_PAUSE = 'start_pause'
|
||||||
|
SERVICE_START = 'start'
|
||||||
|
SERVICE_PAUSE = 'pause'
|
||||||
SERVICE_STOP = 'stop'
|
SERVICE_STOP = 'stop'
|
||||||
|
|
||||||
VACUUM_SERVICE_SCHEMA = vol.Schema({
|
VACUUM_SERVICE_SCHEMA = vol.Schema({
|
||||||
@ -65,6 +67,8 @@ SERVICE_TO_METHOD = {
|
|||||||
SERVICE_TURN_OFF: {'method': 'async_turn_off'},
|
SERVICE_TURN_OFF: {'method': 'async_turn_off'},
|
||||||
SERVICE_TOGGLE: {'method': 'async_toggle'},
|
SERVICE_TOGGLE: {'method': 'async_toggle'},
|
||||||
SERVICE_START_PAUSE: {'method': 'async_start_pause'},
|
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_RETURN_TO_BASE: {'method': 'async_return_to_base'},
|
||||||
SERVICE_CLEAN_SPOT: {'method': 'async_clean_spot'},
|
SERVICE_CLEAN_SPOT: {'method': 'async_clean_spot'},
|
||||||
SERVICE_LOCATE: {'method': 'async_locate'},
|
SERVICE_LOCATE: {'method': 'async_locate'},
|
||||||
@ -97,6 +101,7 @@ SUPPORT_LOCATE = 512
|
|||||||
SUPPORT_CLEAN_SPOT = 1024
|
SUPPORT_CLEAN_SPOT = 1024
|
||||||
SUPPORT_MAP = 2048
|
SUPPORT_MAP = 2048
|
||||||
SUPPORT_STATE = 4096
|
SUPPORT_STATE = 4096
|
||||||
|
SUPPORT_START = 8192
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
@bind_hass
|
||||||
@ -155,6 +160,20 @@ def start_pause(hass, entity_id=None):
|
|||||||
hass.services.call(DOMAIN, SERVICE_START_PAUSE, data)
|
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
|
@bind_hass
|
||||||
def stop(hass, entity_id=None):
|
def stop(hass, entity_id=None):
|
||||||
"""Stop all or specified vacuum."""
|
"""Stop all or specified vacuum."""
|
||||||
@ -242,18 +261,6 @@ class _BaseVacuum(Entity):
|
|||||||
"""Get the list of available fan speed steps of the vacuum cleaner."""
|
"""Get the list of available fan speed steps of the vacuum cleaner."""
|
||||||
raise NotImplementedError()
|
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):
|
def stop(self, **kwargs):
|
||||||
"""Stop the vacuum cleaner."""
|
"""Stop the vacuum cleaner."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
@ -384,6 +391,18 @@ class VacuumDevice(_BaseVacuum, ToggleEntity):
|
|||||||
await self.hass.async_add_executor_job(
|
await self.hass.async_add_executor_job(
|
||||||
partial(self.turn_off, **kwargs))
|
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):
|
class StateVacuumDevice(_BaseVacuum):
|
||||||
"""Representation of a vacuum cleaner robot that supports states."""
|
"""Representation of a vacuum cleaner robot that supports states."""
|
||||||
@ -415,3 +434,25 @@ class StateVacuumDevice(_BaseVacuum):
|
|||||||
data[ATTR_FAN_SPEED_LIST] = self.fan_speed_list
|
data[ATTR_FAN_SPEED_LIST] = self.fan_speed_list
|
||||||
|
|
||||||
return data
|
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)
|
||||||
|
@ -10,8 +10,8 @@ from homeassistant.components.vacuum import (
|
|||||||
ATTR_CLEANED_AREA, SUPPORT_BATTERY, SUPPORT_CLEAN_SPOT,
|
ATTR_CLEANED_AREA, SUPPORT_BATTERY, SUPPORT_CLEAN_SPOT,
|
||||||
SUPPORT_FAN_SPEED, SUPPORT_LOCATE, SUPPORT_PAUSE, SUPPORT_RETURN_HOME,
|
SUPPORT_FAN_SPEED, SUPPORT_LOCATE, SUPPORT_PAUSE, SUPPORT_RETURN_HOME,
|
||||||
SUPPORT_SEND_COMMAND, SUPPORT_STATUS, SUPPORT_STOP, SUPPORT_TURN_OFF,
|
SUPPORT_SEND_COMMAND, SUPPORT_STATUS, SUPPORT_STOP, SUPPORT_TURN_OFF,
|
||||||
SUPPORT_TURN_ON, SUPPORT_STATE, STATE_CLEANING, STATE_DOCKED,
|
SUPPORT_TURN_ON, SUPPORT_STATE, SUPPORT_START, STATE_CLEANING,
|
||||||
STATE_IDLE, STATE_PAUSED, STATE_RETURNING, VacuumDevice,
|
STATE_DOCKED, STATE_IDLE, STATE_PAUSED, STATE_RETURNING, VacuumDevice,
|
||||||
StateVacuumDevice)
|
StateVacuumDevice)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -32,7 +32,7 @@ SUPPORT_ALL_SERVICES = SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PAUSE | \
|
|||||||
|
|
||||||
SUPPORT_STATE_SERVICES = SUPPORT_STATE | SUPPORT_PAUSE | SUPPORT_STOP | \
|
SUPPORT_STATE_SERVICES = SUPPORT_STATE | SUPPORT_PAUSE | SUPPORT_STOP | \
|
||||||
SUPPORT_RETURN_HOME | SUPPORT_FAN_SPEED | \
|
SUPPORT_RETURN_HOME | SUPPORT_FAN_SPEED | \
|
||||||
SUPPORT_BATTERY | SUPPORT_CLEAN_SPOT
|
SUPPORT_BATTERY | SUPPORT_CLEAN_SPOT | SUPPORT_START
|
||||||
|
|
||||||
FAN_SPEEDS = ['min', 'medium', 'high', 'max']
|
FAN_SPEEDS = ['min', 'medium', 'high', 'max']
|
||||||
DEMO_VACUUM_COMPLETE = '0_Ground_floor'
|
DEMO_VACUUM_COMPLETE = '0_Ground_floor'
|
||||||
@ -274,18 +274,25 @@ class StateDemoVacuum(StateVacuumDevice):
|
|||||||
"""Return device state attributes."""
|
"""Return device state attributes."""
|
||||||
return {ATTR_CLEANED_AREA: round(self._cleaned_area, 2)}
|
return {ATTR_CLEANED_AREA: round(self._cleaned_area, 2)}
|
||||||
|
|
||||||
def start_pause(self, **kwargs):
|
def start(self):
|
||||||
"""Start, pause or resume the cleaning task."""
|
"""Start or resume the cleaning task."""
|
||||||
|
if self.supported_features & SUPPORT_START == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._state != STATE_CLEANING:
|
||||||
|
self._state = STATE_CLEANING
|
||||||
|
self._cleaned_area += 1.32
|
||||||
|
self._battery_level -= 1
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
def pause(self):
|
||||||
|
"""Pause the cleaning task."""
|
||||||
if self.supported_features & SUPPORT_PAUSE == 0:
|
if self.supported_features & SUPPORT_PAUSE == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._state == STATE_CLEANING:
|
if self._state == STATE_CLEANING:
|
||||||
self._state = STATE_PAUSED
|
self._state = STATE_PAUSED
|
||||||
else:
|
self.schedule_update_ha_state()
|
||||||
self._state = STATE_CLEANING
|
|
||||||
self._cleaned_area += 1.32
|
|
||||||
self._battery_level -= 1
|
|
||||||
self.schedule_update_ha_state()
|
|
||||||
|
|
||||||
def stop(self, **kwargs):
|
def stop(self, **kwargs):
|
||||||
"""Stop the cleaning task, do not return to dock."""
|
"""Stop the cleaning task, do not return to dock."""
|
||||||
|
@ -35,6 +35,20 @@ start_pause:
|
|||||||
description: Name of the vacuum entity.
|
description: Name of the vacuum entity.
|
||||||
example: 'vacuum.xiaomi_vacuum_cleaner'
|
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:
|
return_to_base:
|
||||||
description: Tell the vacuum cleaner to return to its dock.
|
description: Tell the vacuum cleaner to return to its dock.
|
||||||
fields:
|
fields:
|
||||||
|
@ -83,7 +83,7 @@ class TestVacuumDemo(unittest.TestCase):
|
|||||||
self.assertEqual(STATE_OFF, state.state)
|
self.assertEqual(STATE_OFF, state.state)
|
||||||
|
|
||||||
state = self.hass.states.get(ENTITY_VACUUM_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(STATE_DOCKED, state.state)
|
||||||
self.assertEqual(100, state.attributes.get(ATTR_BATTERY_LEVEL))
|
self.assertEqual(100, state.attributes.get(ATTR_BATTERY_LEVEL))
|
||||||
self.assertEqual("medium", state.attributes.get(ATTR_FAN_SPEED))
|
self.assertEqual("medium", state.attributes.get(ATTR_FAN_SPEED))
|
||||||
@ -158,12 +158,12 @@ class TestVacuumDemo(unittest.TestCase):
|
|||||||
self.assertIn("spot", state.attributes.get(ATTR_STATUS))
|
self.assertIn("spot", state.attributes.get(ATTR_STATUS))
|
||||||
self.assertEqual(STATE_ON, state.state)
|
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()
|
self.hass.block_till_done()
|
||||||
state = self.hass.states.get(ENTITY_VACUUM_STATE)
|
state = self.hass.states.get(ENTITY_VACUUM_STATE)
|
||||||
self.assertEqual(STATE_CLEANING, state.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()
|
self.hass.block_till_done()
|
||||||
state = self.hass.states.get(ENTITY_VACUUM_STATE)
|
state = self.hass.states.get(ENTITY_VACUUM_STATE)
|
||||||
self.assertEqual(STATE_PAUSED, state.state)
|
self.assertEqual(STATE_PAUSED, state.state)
|
||||||
@ -247,6 +247,23 @@ class TestVacuumDemo(unittest.TestCase):
|
|||||||
self.assertNotIn("spot", state.attributes.get(ATTR_STATUS))
|
self.assertNotIn("spot", state.attributes.get(ATTR_STATUS))
|
||||||
self.assertEqual(STATE_OFF, state.state)
|
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
|
# StateVacuumDevice does not support on/off
|
||||||
vacuum.turn_on(self.hass, entity_id=ENTITY_VACUUM_STATE)
|
vacuum.turn_on(self.hass, entity_id=ENTITY_VACUUM_STATE)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
Loading…
Reference in New Issue
Block a user