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:
Joakim Plate 2019-04-25 22:12:11 +02:00 committed by Paulus Schoutsen
parent 7e8f2d72b6
commit 39932d132d
5 changed files with 68 additions and 6 deletions

View File

@ -51,7 +51,7 @@ class AbstractDemoPlayer(MediaPlayerDevice):
# We only implement the methods that we support
def __init__(self, name):
def __init__(self, name, device_class=None):
"""Initialize the demo device."""
self._name = name
self._player_state = STATE_PLAYING
@ -60,6 +60,7 @@ class AbstractDemoPlayer(MediaPlayerDevice):
self._shuffle = False
self._sound_mode_list = SOUND_MODE_LIST
self._sound_mode = DEFAULT_SOUND_MODE
self._device_class = device_class
@property
def should_poll(self):
@ -101,6 +102,11 @@ class AbstractDemoPlayer(MediaPlayerDevice):
"""Return a list of available sound modes."""
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):
"""Turn the media player on."""
self._player_state = STATE_PLAYING

View File

@ -51,6 +51,9 @@ TYPE_GARAGE = PREFIX_TYPES + 'GARAGE'
TYPE_OUTLET = PREFIX_TYPES + 'OUTLET'
TYPE_SENSOR = PREFIX_TYPES + 'SENSOR'
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'
HOMEGRAPH_URL = 'https://homegraph.googleapis.com/'
@ -86,7 +89,7 @@ DOMAIN_TO_GOOGLE_TYPES = {
input_boolean.DOMAIN: TYPE_SWITCH,
light.DOMAIN: TYPE_LIGHT,
lock.DOMAIN: TYPE_LOCK,
media_player.DOMAIN: TYPE_SWITCH,
media_player.DOMAIN: TYPE_MEDIA,
scene.DOMAIN: TYPE_SCENE,
script.DOMAIN: TYPE_SCENE,
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_OPENING): 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'

View File

@ -66,6 +66,16 @@ ENTITY_IMAGE_CACHE = {
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
MEDIA_PLAYER_SCHEMA = vol.Schema({
ATTR_ENTITY_ID: cv.comp_entity_ids,

View File

@ -147,7 +147,7 @@ DEMO_DEVICES = [{
'action.devices.traits.Modes'
],
'type':
'action.devices.types.SWITCH',
'action.devices.types.MEDIA',
'willReportState':
False
}, {
@ -162,7 +162,7 @@ DEMO_DEVICES = [{
'action.devices.traits.Modes'
],
'type':
'action.devices.types.SWITCH',
'action.devices.types.MEDIA',
'willReportState':
False
}, {
@ -171,7 +171,7 @@ DEMO_DEVICES = [{
'name': 'Lounge room'
},
'traits': ['action.devices.traits.OnOff', 'action.devices.traits.Modes'],
'type': 'action.devices.types.SWITCH',
'type': 'action.devices.types.MEDIA',
'willReportState': False
}, {
'id':
@ -182,7 +182,7 @@ DEMO_DEVICES = [{
'traits':
['action.devices.traits.OnOff', 'action.devices.traits.Volume'],
'type':
'action.devices.types.SWITCH',
'action.devices.types.MEDIA',
'willReportState':
False
}, {

View File

@ -16,6 +16,7 @@ from homeassistant.components.google_assistant import (
from homeassistant.components.demo.binary_sensor import DemoBinarySensor
from homeassistant.components.demo.cover import DemoCover
from homeassistant.components.demo.light import DemoLight
from homeassistant.components.demo.media_player import AbstractDemoPlayer
from homeassistant.components.demo.switch import DemoSwitch
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):
"""Test a disconnect message."""
result = await sh.async_handle_message(