Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for vacuum cleaner and traits #15575

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions homeassistant/components/google_assistant/const.py
Expand Up @@ -27,6 +27,7 @@
TYPE_SWITCH = PREFIX_TYPES + 'SWITCH'
TYPE_SCENE = PREFIX_TYPES + 'SCENE'
TYPE_THERMOSTAT = PREFIX_TYPES + 'THERMOSTAT'
TYPE_VACUUM = PREFIX_TYPES + 'VACUUM'

SERVICE_REQUEST_SYNC = 'request_sync'
HOMEGRAPH_URL = 'https://homegraph.googleapis.com/'
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/google_assistant/smart_home.py
Expand Up @@ -19,12 +19,13 @@
scene,
script,
switch,
vacuum,
)

from . import trait
from .const import (
TYPE_LIGHT, TYPE_SCENE, TYPE_SWITCH, TYPE_THERMOSTAT,
CONF_ALIASES, CONF_ROOM_HINT,
TYPE_VACUUM, CONF_ALIASES, CONF_ROOM_HINT,
ERR_NOT_SUPPORTED, ERR_PROTOCOL_ERROR, ERR_DEVICE_OFFLINE,
ERR_UNKNOWN_ERROR
)
Expand All @@ -44,6 +45,7 @@
scene.DOMAIN: TYPE_SCENE,
script.DOMAIN: TYPE_SCENE,
switch.DOMAIN: TYPE_SWITCH,
vacuum.DOMAIN: TYPE_VACUUM,
}


Expand Down
133 changes: 132 additions & 1 deletion homeassistant/components/google_assistant/trait.py
Expand Up @@ -11,10 +11,12 @@
scene,
script,
switch,
vacuum,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_UNIT_OF_MEASUREMENT,
ATTR_SUPPORTED_FEATURES,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
Expand All @@ -33,6 +35,8 @@
TRAIT_COLOR_TEMP = PREFIX_TRAITS + 'ColorTemperature'
TRAIT_SCENE = PREFIX_TRAITS + 'Scene'
TRAIT_TEMPERATURE_SETTING = PREFIX_TRAITS + 'TemperatureSetting'
TRAIT_STARTSTOP = PREFIX_TRAITS + 'StartStop'
TRAIT_DOCK = PREFIX_TRAITS + 'Dock'

PREFIX_COMMANDS = 'action.devices.commands.'
COMMAND_ONOFF = PREFIX_COMMANDS + 'OnOff'
Expand All @@ -44,7 +48,9 @@
COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE = (
PREFIX_COMMANDS + 'ThermostatTemperatureSetRange')
COMMAND_THERMOSTAT_SET_MODE = PREFIX_COMMANDS + 'ThermostatSetMode'

COMMAND_STARTSTOP = PREFIX_COMMANDS + 'StartStop'
COMMAND_PAUSEUNPAUSE = PREFIX_COMMANDS + 'PauseUnpause'
COMMAND_DOCK = PREFIX_COMMANDS + 'Dock'

TRAITS = []

Expand Down Expand Up @@ -520,3 +526,128 @@ async def execute(self, hass, command, params):
climate.ATTR_OPERATION_MODE:
self.google_to_hass[params['thermostatMode']],
}, blocking=True)


@register_trait
class StartStopTrait(_Trait):
"""Trait to offer start, stop, and pause functionality.

https://developers.google.com/actions/smarthome/traits/startstop
"""

name = TRAIT_STARTSTOP
commands = [
COMMAND_STARTSTOP,
COMMAND_PAUSEUNPAUSE
]

@staticmethod
def supported(domain, features):
"""Test if state is supported."""
if domain == vacuum.DOMAIN:
return features & vacuum.SUPPORT_STATE

Copy link
Contributor

@arbreng arbreng Aug 1, 2018

Choose a reason for hiding this comment

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

return features & vacuum.SUPPORT_STATE

Probably a good idea to check for SUPPORT_STATE here. That will exclude any platforms that haven't been ported yet

return False

def sync_attributes(self):
"""Return if vacuum is pausable."""
return {'pausable': (self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
& vacuum.SUPPORT_PAUSE) != 0}

def query_attributes(self):
"""Return the running/paused state."""
domain = self.state.domain
response = {}

if domain == vacuum.DOMAIN:

state = self.state.state

if state == vacuum.STATE_PAUSED:
response['isPaused'] = True
response['isRunning'] = False
elif state == vacuum.STATE_CLEANING:
response['isPaused'] = False
response['isRunning'] = True
else:
response['isPaused'] = False
response['isRunning'] = False

return response

async def execute(self, hass, command, params):
"""Execute a start, stop, pause, or unpause command."""
domain = self.state.domain
param_start = 'start'
param_pause = 'pause'
start_stop_command = 'action.devices.commands.StartStop'
pause_unpause_command = 'action.devices.commands.PauseUnpause'

if domain == vacuum.DOMAIN:
service_domain = domain
state = self.state.state

if command == start_stop_command:
Copy link
Member

Choose a reason for hiding this comment

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

if command == COMMAND_STARTSTOP: ?

if params[param_start]:
service = vacuum.SERVICE_START
else:
service = vacuum.SERVICE_STOP

if command == pause_unpause_command:
Copy link
Member

Choose a reason for hiding this comment

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

COMMAND_PAUSEUNPAUSE ?

if params[param_pause]:
if state == vacuum.STATE_CLEANING:
service = vacuum.SERVICE_PAUSE
else:
if state == vacuum.STATE_PAUSED:
service = vacuum.SERVICE_START

await hass.services.async_call(service_domain, service, {
ATTR_ENTITY_ID: self.state.entity_id
}, blocking=True)


@register_trait
class DockTrait(_Trait):
"""Trait to offer docking.

https://developers.google.com/actions/smarthome/traits/dock
"""

name = TRAIT_DOCK
commands = {COMMAND_DOCK}

@staticmethod
def supported(domain, features):
"""Test if state is supported."""
if domain == vacuum.DOMAIN:
return features & vacuum.SUPPORT_STATE

return False

def sync_attributes(self):
"""No attributes required."""
return {}

def query_attributes(self):
"""Return if docked."""
domain = self.state.domain
response = {}

if domain == vacuum.DOMAIN:
state = self.state.state

response['isDocked'] = bool(state == vacuum.STATE_DOCKED)

return response

async def execute(self, hass, command, params):
"""Execute a return to dock command."""
domain = self.state.domain

if domain == vacuum.DOMAIN:
service_domain = domain
service = vacuum.SERVICE_RETURN_TO_BASE

await hass.services.async_call(service_domain, service, {
ATTR_ENTITY_ID: self.state.entity_id
}, blocking=True)