Skip to content
Snippets Groups Projects
Commit 9064058a authored by Josh Bendavid's avatar Josh Bendavid Committed by springstan
Browse files

Add generic command functionality to denonavr (#29295)

* Add generic command functionality to denonavr

* add minimal unit tests for denonavr

* fix import order

* simplify denonavr unit test

* handle domain specific service calls with dispatcher

* update unit tests

* update unit tests

* remove unnecessary return value

* fix handling of mock instances in unit tests
parent b91cbb50
No related branches found
No related tags found
No related merge requests found
"""The denonavr component."""
import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send
DOMAIN = "denonavr"
SERVICE_GET_COMMAND = "get_command"
ATTR_COMMAND = "command"
CALL_SCHEMA = vol.Schema({vol.Required(ATTR_ENTITY_ID): cv.comp_entity_ids})
GET_COMMAND_SCHEMA = CALL_SCHEMA.extend({vol.Required(ATTR_COMMAND): cv.string})
SERVICE_TO_METHOD = {
SERVICE_GET_COMMAND: {"method": "get_command", "schema": GET_COMMAND_SCHEMA}
}
def setup(hass, config):
"""Set up the denonavr platform."""
def service_handler(service):
method = SERVICE_TO_METHOD.get(service.service)
data = service.data.copy()
data["method"] = method["method"]
dispatcher_send(hass, DOMAIN, data)
for service in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[service]["schema"]
hass.services.register(DOMAIN, service, service_handler, schema=schema)
return True
......@@ -24,16 +24,21 @@ from homeassistant.components.media_player.const import (
SUPPORT_VOLUME_STEP,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_HOST,
CONF_NAME,
CONF_TIMEOUT,
CONF_ZONE,
ENTITY_MATCH_ALL,
STATE_OFF,
STATE_ON,
STATE_PAUSED,
STATE_PLAYING,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from . import DOMAIN
_LOGGER = logging.getLogger(__name__)
......@@ -190,6 +195,21 @@ class DenonDevice(MediaPlayerDevice):
self._sound_mode_support and SUPPORT_SELECT_SOUND_MODE
)
async def async_added_to_hass(self):
"""Register signal handler."""
async_dispatcher_connect(self.hass, DOMAIN, self.signal_handler)
def signal_handler(self, data):
"""Handle domain-specific signal by calling appropriate method."""
entity_ids = data[ATTR_ENTITY_ID]
if entity_ids == ENTITY_MATCH_ALL or self.entity_id in entity_ids:
params = {
key: value
for key, value in data.items()
if key not in ["entity_id", "method"]
}
getattr(self, data["method"])(**params)
def update(self):
"""Get the latest status information from device."""
self._receiver.update()
......@@ -398,3 +418,7 @@ class DenonDevice(MediaPlayerDevice):
def mute_volume(self, mute):
"""Send mute command."""
return self._receiver.mute(mute)
def get_command(self, command, **kwargs):
"""Send generic command."""
self._receiver.send_get_command(command)
# Describes the format for available webostv services
get_command:
description: 'Send a generic http get command.'
fields:
entity_id:
description: Name(s) of the denonavr entities where to run the API method.
example: 'media_player.living_room_receiver'
command:
description: Endpoint of the command, including associated parameters.
example: '/goform/formiPhoneAppDirect.xml?RCKSK0410370'
......@@ -149,6 +149,9 @@ datadog==0.15.0
# homeassistant.components.ssdp
defusedxml==0.6.0
# homeassistant.components.denonavr
denonavr==0.7.10
# homeassistant.components.directv
directpy==0.5
......
"""Tests for the denonavr integration."""
"""The tests for the denonavr media player platform."""
from unittest.mock import patch
import pytest
from homeassistant.components import media_player
from homeassistant.components.denonavr import ATTR_COMMAND, DOMAIN, SERVICE_GET_COMMAND
from homeassistant.const import ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_PLATFORM
from homeassistant.setup import async_setup_component
NAME = "fake"
ENTITY_ID = f"{media_player.DOMAIN}.{NAME}"
@pytest.fixture(name="client")
def client_fixture():
"""Patch of client library for tests."""
with patch(
"homeassistant.components.denonavr.media_player.denonavr.DenonAVR",
autospec=True,
) as mock_client_class, patch(
"homeassistant.components.denonavr.media_player.denonavr.discover"
):
mock_client_class.return_value.name = NAME
mock_client_class.return_value.zones = {"Main": mock_client_class.return_value}
yield mock_client_class.return_value
async def setup_denonavr(hass):
"""Initialize webostv and media_player for tests."""
assert await async_setup_component(
hass,
media_player.DOMAIN,
{
media_player.DOMAIN: {
CONF_PLATFORM: "denonavr",
CONF_HOST: "fake",
CONF_NAME: NAME,
}
},
)
await hass.async_block_till_done()
async def test_get_command(hass, client):
"""Test generic command functionality."""
await setup_denonavr(hass)
data = {
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_COMMAND: "test",
}
await hass.services.async_call(DOMAIN, SERVICE_GET_COMMAND, data)
await hass.async_block_till_done()
client.send_get_command.assert_called_with("test")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment