mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Add device classes for media player and map to google types (#23236)
* Add device classes for media player and map to google types * Switch default class for media_player to media
This commit is contained in:
parent
7e8f2d72b6
commit
39932d132d
@ -51,7 +51,7 @@ class AbstractDemoPlayer(MediaPlayerDevice):
|
|||||||
|
|
||||||
# We only implement the methods that we support
|
# We only implement the methods that we support
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name, device_class=None):
|
||||||
"""Initialize the demo device."""
|
"""Initialize the demo device."""
|
||||||
self._name = name
|
self._name = name
|
||||||
self._player_state = STATE_PLAYING
|
self._player_state = STATE_PLAYING
|
||||||
@ -60,6 +60,7 @@ class AbstractDemoPlayer(MediaPlayerDevice):
|
|||||||
self._shuffle = False
|
self._shuffle = False
|
||||||
self._sound_mode_list = SOUND_MODE_LIST
|
self._sound_mode_list = SOUND_MODE_LIST
|
||||||
self._sound_mode = DEFAULT_SOUND_MODE
|
self._sound_mode = DEFAULT_SOUND_MODE
|
||||||
|
self._device_class = device_class
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
@ -101,6 +102,11 @@ class AbstractDemoPlayer(MediaPlayerDevice):
|
|||||||
"""Return a list of available sound modes."""
|
"""Return a list of available sound modes."""
|
||||||
return self._sound_mode_list
|
return self._sound_mode_list
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_class(self):
|
||||||
|
"""Return the device class of the media player."""
|
||||||
|
return self._device_class
|
||||||
|
|
||||||
def turn_on(self):
|
def turn_on(self):
|
||||||
"""Turn the media player on."""
|
"""Turn the media player on."""
|
||||||
self._player_state = STATE_PLAYING
|
self._player_state = STATE_PLAYING
|
||||||
|
@ -51,6 +51,9 @@ TYPE_GARAGE = PREFIX_TYPES + 'GARAGE'
|
|||||||
TYPE_OUTLET = PREFIX_TYPES + 'OUTLET'
|
TYPE_OUTLET = PREFIX_TYPES + 'OUTLET'
|
||||||
TYPE_SENSOR = PREFIX_TYPES + 'SENSOR'
|
TYPE_SENSOR = PREFIX_TYPES + 'SENSOR'
|
||||||
TYPE_DOOR = PREFIX_TYPES + 'DOOR'
|
TYPE_DOOR = PREFIX_TYPES + 'DOOR'
|
||||||
|
TYPE_TV = PREFIX_TYPES + 'TV'
|
||||||
|
TYPE_SPEAKER = PREFIX_TYPES + 'SPEAKER'
|
||||||
|
TYPE_MEDIA = PREFIX_TYPES + 'MEDIA'
|
||||||
|
|
||||||
SERVICE_REQUEST_SYNC = 'request_sync'
|
SERVICE_REQUEST_SYNC = 'request_sync'
|
||||||
HOMEGRAPH_URL = 'https://homegraph.googleapis.com/'
|
HOMEGRAPH_URL = 'https://homegraph.googleapis.com/'
|
||||||
@ -86,7 +89,7 @@ DOMAIN_TO_GOOGLE_TYPES = {
|
|||||||
input_boolean.DOMAIN: TYPE_SWITCH,
|
input_boolean.DOMAIN: TYPE_SWITCH,
|
||||||
light.DOMAIN: TYPE_LIGHT,
|
light.DOMAIN: TYPE_LIGHT,
|
||||||
lock.DOMAIN: TYPE_LOCK,
|
lock.DOMAIN: TYPE_LOCK,
|
||||||
media_player.DOMAIN: TYPE_SWITCH,
|
media_player.DOMAIN: TYPE_MEDIA,
|
||||||
scene.DOMAIN: TYPE_SCENE,
|
scene.DOMAIN: TYPE_SCENE,
|
||||||
script.DOMAIN: TYPE_SCENE,
|
script.DOMAIN: TYPE_SCENE,
|
||||||
switch.DOMAIN: TYPE_SWITCH,
|
switch.DOMAIN: TYPE_SWITCH,
|
||||||
@ -104,6 +107,8 @@ DEVICE_CLASS_TO_GOOGLE_TYPES = {
|
|||||||
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_LOCK): TYPE_SENSOR,
|
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_LOCK): TYPE_SENSOR,
|
||||||
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_OPENING): TYPE_SENSOR,
|
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_OPENING): TYPE_SENSOR,
|
||||||
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_WINDOW): TYPE_SENSOR,
|
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_WINDOW): TYPE_SENSOR,
|
||||||
|
(media_player.DOMAIN, media_player.DEVICE_CLASS_TV): TYPE_TV,
|
||||||
|
(media_player.DOMAIN, media_player.DEVICE_CLASS_SPEAKER): TYPE_SPEAKER,
|
||||||
}
|
}
|
||||||
|
|
||||||
CHALLENGE_ACK_NEEDED = 'ackNeeded'
|
CHALLENGE_ACK_NEEDED = 'ackNeeded'
|
||||||
|
@ -66,6 +66,16 @@ ENTITY_IMAGE_CACHE = {
|
|||||||
|
|
||||||
SCAN_INTERVAL = timedelta(seconds=10)
|
SCAN_INTERVAL = timedelta(seconds=10)
|
||||||
|
|
||||||
|
DEVICE_CLASS_TV = 'tv'
|
||||||
|
DEVICE_CLASS_SPEAKER = 'speaker'
|
||||||
|
|
||||||
|
DEVICE_CLASSES = [
|
||||||
|
DEVICE_CLASS_TV,
|
||||||
|
DEVICE_CLASS_SPEAKER,
|
||||||
|
]
|
||||||
|
|
||||||
|
DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(DEVICE_CLASSES))
|
||||||
|
|
||||||
# Service call validation schemas
|
# Service call validation schemas
|
||||||
MEDIA_PLAYER_SCHEMA = vol.Schema({
|
MEDIA_PLAYER_SCHEMA = vol.Schema({
|
||||||
ATTR_ENTITY_ID: cv.comp_entity_ids,
|
ATTR_ENTITY_ID: cv.comp_entity_ids,
|
||||||
|
@ -147,7 +147,7 @@ DEMO_DEVICES = [{
|
|||||||
'action.devices.traits.Modes'
|
'action.devices.traits.Modes'
|
||||||
],
|
],
|
||||||
'type':
|
'type':
|
||||||
'action.devices.types.SWITCH',
|
'action.devices.types.MEDIA',
|
||||||
'willReportState':
|
'willReportState':
|
||||||
False
|
False
|
||||||
}, {
|
}, {
|
||||||
@ -162,7 +162,7 @@ DEMO_DEVICES = [{
|
|||||||
'action.devices.traits.Modes'
|
'action.devices.traits.Modes'
|
||||||
],
|
],
|
||||||
'type':
|
'type':
|
||||||
'action.devices.types.SWITCH',
|
'action.devices.types.MEDIA',
|
||||||
'willReportState':
|
'willReportState':
|
||||||
False
|
False
|
||||||
}, {
|
}, {
|
||||||
@ -171,7 +171,7 @@ DEMO_DEVICES = [{
|
|||||||
'name': 'Lounge room'
|
'name': 'Lounge room'
|
||||||
},
|
},
|
||||||
'traits': ['action.devices.traits.OnOff', 'action.devices.traits.Modes'],
|
'traits': ['action.devices.traits.OnOff', 'action.devices.traits.Modes'],
|
||||||
'type': 'action.devices.types.SWITCH',
|
'type': 'action.devices.types.MEDIA',
|
||||||
'willReportState': False
|
'willReportState': False
|
||||||
}, {
|
}, {
|
||||||
'id':
|
'id':
|
||||||
@ -182,7 +182,7 @@ DEMO_DEVICES = [{
|
|||||||
'traits':
|
'traits':
|
||||||
['action.devices.traits.OnOff', 'action.devices.traits.Volume'],
|
['action.devices.traits.OnOff', 'action.devices.traits.Volume'],
|
||||||
'type':
|
'type':
|
||||||
'action.devices.types.SWITCH',
|
'action.devices.types.MEDIA',
|
||||||
'willReportState':
|
'willReportState':
|
||||||
False
|
False
|
||||||
}, {
|
}, {
|
||||||
|
@ -16,6 +16,7 @@ from homeassistant.components.google_assistant import (
|
|||||||
from homeassistant.components.demo.binary_sensor import DemoBinarySensor
|
from homeassistant.components.demo.binary_sensor import DemoBinarySensor
|
||||||
from homeassistant.components.demo.cover import DemoCover
|
from homeassistant.components.demo.cover import DemoCover
|
||||||
from homeassistant.components.demo.light import DemoLight
|
from homeassistant.components.demo.light import DemoLight
|
||||||
|
from homeassistant.components.demo.media_player import AbstractDemoPlayer
|
||||||
from homeassistant.components.demo.switch import DemoSwitch
|
from homeassistant.components.demo.switch import DemoSwitch
|
||||||
|
|
||||||
from homeassistant.helpers import device_registry
|
from homeassistant.helpers import device_registry
|
||||||
@ -684,6 +685,46 @@ async def test_device_class_cover(hass, device_class, google_type):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("device_class,google_type", [
|
||||||
|
('non_existing_class', 'action.devices.types.MEDIA'),
|
||||||
|
('speaker', 'action.devices.types.SPEAKER'),
|
||||||
|
('tv', 'action.devices.types.TV'),
|
||||||
|
])
|
||||||
|
async def test_device_media_player(hass, device_class, google_type):
|
||||||
|
"""Test that a binary entity syncs to the correct device type."""
|
||||||
|
sensor = AbstractDemoPlayer(
|
||||||
|
'Demo',
|
||||||
|
device_class=device_class
|
||||||
|
)
|
||||||
|
sensor.hass = hass
|
||||||
|
sensor.entity_id = 'media_player.demo'
|
||||||
|
await sensor.async_update_ha_state()
|
||||||
|
|
||||||
|
result = await sh.async_handle_message(
|
||||||
|
hass, BASIC_CONFIG, 'test-agent',
|
||||||
|
{
|
||||||
|
"requestId": REQ_ID,
|
||||||
|
"inputs": [{
|
||||||
|
"intent": "action.devices.SYNC"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result == {
|
||||||
|
'requestId': REQ_ID,
|
||||||
|
'payload': {
|
||||||
|
'agentUserId': 'test-agent',
|
||||||
|
'devices': [{
|
||||||
|
'attributes': {},
|
||||||
|
'id': sensor.entity_id,
|
||||||
|
'name': {'name': sensor.name},
|
||||||
|
'traits': ['action.devices.traits.OnOff'],
|
||||||
|
'type': google_type,
|
||||||
|
'willReportState': False
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_query_disconnect(hass):
|
async def test_query_disconnect(hass):
|
||||||
"""Test a disconnect message."""
|
"""Test a disconnect message."""
|
||||||
result = await sh.async_handle_message(
|
result = await sh.async_handle_message(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user