mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 01:37:08 +00:00
Implement google_assistant ModesTrait for input_select (#36313)
This commit is contained in:
parent
a333417ddf
commit
47706dac1a
@ -8,6 +8,7 @@ from homeassistant.components import (
|
||||
fan,
|
||||
group,
|
||||
input_boolean,
|
||||
input_select,
|
||||
light,
|
||||
lock,
|
||||
media_player,
|
||||
@ -44,6 +45,7 @@ DEFAULT_EXPOSED_DOMAINS = [
|
||||
"fan",
|
||||
"group",
|
||||
"input_boolean",
|
||||
"input_select",
|
||||
"light",
|
||||
"media_player",
|
||||
"scene",
|
||||
@ -113,6 +115,7 @@ DOMAIN_TO_GOOGLE_TYPES = {
|
||||
fan.DOMAIN: TYPE_FAN,
|
||||
group.DOMAIN: TYPE_SWITCH,
|
||||
input_boolean.DOMAIN: TYPE_SWITCH,
|
||||
input_select.DOMAIN: TYPE_SENSOR,
|
||||
light.DOMAIN: TYPE_LIGHT,
|
||||
lock.DOMAIN: TYPE_LOCK,
|
||||
media_player.DOMAIN: TYPE_SETTOP,
|
||||
|
@ -9,6 +9,7 @@ from homeassistant.components import (
|
||||
fan,
|
||||
group,
|
||||
input_boolean,
|
||||
input_select,
|
||||
light,
|
||||
lock,
|
||||
media_player,
|
||||
@ -1131,11 +1132,15 @@ class ModesTrait(_Trait):
|
||||
SYNONYMS = {
|
||||
"input source": ["input source", "input", "source"],
|
||||
"sound mode": ["sound mode", "effects"],
|
||||
"option": ["option", "setting", "mode", "value"],
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def supported(domain, features, device_class):
|
||||
"""Test if state is supported."""
|
||||
if domain == input_select.DOMAIN:
|
||||
return True
|
||||
|
||||
if domain != media_player.DOMAIN:
|
||||
return False
|
||||
|
||||
@ -1174,15 +1179,20 @@ class ModesTrait(_Trait):
|
||||
|
||||
attrs = self.state.attributes
|
||||
modes = []
|
||||
if media_player.ATTR_INPUT_SOURCE_LIST in attrs:
|
||||
modes.append(
|
||||
_generate("input source", attrs[media_player.ATTR_INPUT_SOURCE_LIST])
|
||||
)
|
||||
if self.state.domain == media_player.DOMAIN:
|
||||
if media_player.ATTR_INPUT_SOURCE_LIST in attrs:
|
||||
modes.append(
|
||||
_generate(
|
||||
"input source", attrs[media_player.ATTR_INPUT_SOURCE_LIST]
|
||||
)
|
||||
)
|
||||
|
||||
if media_player.ATTR_SOUND_MODE_LIST in attrs:
|
||||
modes.append(
|
||||
_generate("sound mode", attrs[media_player.ATTR_SOUND_MODE_LIST])
|
||||
)
|
||||
if media_player.ATTR_SOUND_MODE_LIST in attrs:
|
||||
modes.append(
|
||||
_generate("sound mode", attrs[media_player.ATTR_SOUND_MODE_LIST])
|
||||
)
|
||||
elif self.state.domain == input_select.DOMAIN:
|
||||
modes.append(_generate("option", attrs[input_select.ATTR_OPTIONS]))
|
||||
|
||||
payload = {"availableModes": modes}
|
||||
|
||||
@ -1194,11 +1204,16 @@ class ModesTrait(_Trait):
|
||||
response = {}
|
||||
mode_settings = {}
|
||||
|
||||
if media_player.ATTR_INPUT_SOURCE_LIST in attrs:
|
||||
mode_settings["input source"] = attrs.get(media_player.ATTR_INPUT_SOURCE)
|
||||
if self.state.domain == media_player.DOMAIN:
|
||||
if media_player.ATTR_INPUT_SOURCE_LIST in attrs:
|
||||
mode_settings["input source"] = attrs.get(
|
||||
media_player.ATTR_INPUT_SOURCE
|
||||
)
|
||||
|
||||
if media_player.ATTR_SOUND_MODE_LIST in attrs:
|
||||
mode_settings["sound mode"] = attrs.get(media_player.ATTR_SOUND_MODE)
|
||||
if media_player.ATTR_SOUND_MODE_LIST in attrs:
|
||||
mode_settings["sound mode"] = attrs.get(media_player.ATTR_SOUND_MODE)
|
||||
elif self.state.domain == input_select.DOMAIN:
|
||||
mode_settings["option"] = self.state.state
|
||||
|
||||
if mode_settings:
|
||||
response["on"] = self.state.state != STATE_OFF
|
||||
@ -1210,6 +1225,28 @@ class ModesTrait(_Trait):
|
||||
async def execute(self, command, data, params, challenge):
|
||||
"""Execute an SetModes command."""
|
||||
settings = params.get("updateModeSettings")
|
||||
|
||||
if self.state.domain == input_select.DOMAIN:
|
||||
option = params["updateModeSettings"]["option"]
|
||||
await self.hass.services.async_call(
|
||||
input_select.DOMAIN,
|
||||
input_select.SERVICE_SELECT_OPTION,
|
||||
{
|
||||
ATTR_ENTITY_ID: self.state.entity_id,
|
||||
input_select.ATTR_OPTION: option,
|
||||
},
|
||||
blocking=True,
|
||||
context=data.context,
|
||||
)
|
||||
|
||||
return
|
||||
if self.state.domain != media_player.DOMAIN:
|
||||
_LOGGER.info(
|
||||
"Received an Options command for unrecognised domain %s",
|
||||
self.state.domain,
|
||||
)
|
||||
return
|
||||
|
||||
requested_source = settings.get("input source")
|
||||
sound_mode = settings.get("sound mode")
|
||||
|
||||
|
@ -11,6 +11,7 @@ from homeassistant.components import (
|
||||
fan,
|
||||
group,
|
||||
input_boolean,
|
||||
input_select,
|
||||
light,
|
||||
lock,
|
||||
media_player,
|
||||
@ -1267,8 +1268,8 @@ async def test_fan_speed(hass):
|
||||
assert calls[0].data == {"entity_id": "fan.living_room_fan", "speed": "medium"}
|
||||
|
||||
|
||||
async def test_modes(hass):
|
||||
"""Test Mode trait."""
|
||||
async def test_modes_media_player(hass):
|
||||
"""Test Media Player Mode trait."""
|
||||
assert helpers.get_google_type(media_player.DOMAIN, None) is not None
|
||||
assert trait.ModesTrait.supported(
|
||||
media_player.DOMAIN, media_player.SUPPORT_SELECT_SOURCE, None
|
||||
@ -1351,6 +1352,72 @@ async def test_modes(hass):
|
||||
assert calls[0].data == {"entity_id": "media_player.living_room", "source": "media"}
|
||||
|
||||
|
||||
async def test_modes_input_select(hass):
|
||||
"""Test Input Select Mode trait."""
|
||||
assert helpers.get_google_type(input_select.DOMAIN, None) is not None
|
||||
assert trait.ModesTrait.supported(input_select.DOMAIN, None, None)
|
||||
|
||||
trt = trait.ModesTrait(
|
||||
hass,
|
||||
State(
|
||||
"input_select.bla",
|
||||
"abc",
|
||||
attributes={input_select.ATTR_OPTIONS: ["abc", "123", "xyz"]},
|
||||
),
|
||||
BASIC_CONFIG,
|
||||
)
|
||||
|
||||
attribs = trt.sync_attributes()
|
||||
assert attribs == {
|
||||
"availableModes": [
|
||||
{
|
||||
"name": "option",
|
||||
"name_values": [
|
||||
{
|
||||
"name_synonym": ["option", "setting", "mode", "value"],
|
||||
"lang": "en",
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"setting_name": "abc",
|
||||
"setting_values": [{"setting_synonym": ["abc"], "lang": "en"}],
|
||||
},
|
||||
{
|
||||
"setting_name": "123",
|
||||
"setting_values": [{"setting_synonym": ["123"], "lang": "en"}],
|
||||
},
|
||||
{
|
||||
"setting_name": "xyz",
|
||||
"setting_values": [{"setting_synonym": ["xyz"], "lang": "en"}],
|
||||
},
|
||||
],
|
||||
"ordered": False,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
assert trt.query_attributes() == {
|
||||
"currentModeSettings": {"option": "abc"},
|
||||
"on": True,
|
||||
"online": True,
|
||||
}
|
||||
|
||||
assert trt.can_execute(
|
||||
trait.COMMAND_MODES, params={"updateModeSettings": {"option": "xyz"}},
|
||||
)
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, input_select.DOMAIN, input_select.SERVICE_SELECT_OPTION
|
||||
)
|
||||
await trt.execute(
|
||||
trait.COMMAND_MODES, BASIC_DATA, {"updateModeSettings": {"option": "xyz"}}, {},
|
||||
)
|
||||
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data == {"entity_id": "input_select.bla", "option": "xyz"}
|
||||
|
||||
|
||||
async def test_sound_modes(hass):
|
||||
"""Test Mode trait."""
|
||||
assert helpers.get_google_type(media_player.DOMAIN, None) is not None
|
||||
|
Loading…
x
Reference in New Issue
Block a user