Improve RemoteEntity class (#40605)
This commit is contained in:
parent
1355d285e8
commit
d96a1744f0
4 changed files with 91 additions and 0 deletions
|
@ -30,6 +30,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ATTR_ACTIVITY = "activity"
|
ATTR_ACTIVITY = "activity"
|
||||||
ATTR_COMMAND = "command"
|
ATTR_COMMAND = "command"
|
||||||
|
ATTR_COMMAND_TYPE = "command_type"
|
||||||
ATTR_DEVICE = "device"
|
ATTR_DEVICE = "device"
|
||||||
ATTR_NUM_REPEATS = "num_repeats"
|
ATTR_NUM_REPEATS = "num_repeats"
|
||||||
ATTR_DELAY_SECS = "delay_secs"
|
ATTR_DELAY_SECS = "delay_secs"
|
||||||
|
@ -46,6 +47,7 @@ MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
|
||||||
|
|
||||||
SERVICE_SEND_COMMAND = "send_command"
|
SERVICE_SEND_COMMAND = "send_command"
|
||||||
SERVICE_LEARN_COMMAND = "learn_command"
|
SERVICE_LEARN_COMMAND = "learn_command"
|
||||||
|
SERVICE_DELETE_COMMAND = "delete_command"
|
||||||
SERVICE_SYNC = "sync"
|
SERVICE_SYNC = "sync"
|
||||||
|
|
||||||
DEFAULT_NUM_REPEATS = 1
|
DEFAULT_NUM_REPEATS = 1
|
||||||
|
@ -53,6 +55,7 @@ DEFAULT_DELAY_SECS = 0.4
|
||||||
DEFAULT_HOLD_SECS = 0
|
DEFAULT_HOLD_SECS = 0
|
||||||
|
|
||||||
SUPPORT_LEARN_COMMAND = 1
|
SUPPORT_LEARN_COMMAND = 1
|
||||||
|
SUPPORT_DELETE_COMMAND = 2
|
||||||
|
|
||||||
REMOTE_SERVICE_ACTIVITY_SCHEMA = make_entity_service_schema(
|
REMOTE_SERVICE_ACTIVITY_SCHEMA = make_entity_service_schema(
|
||||||
{vol.Optional(ATTR_ACTIVITY): cv.string}
|
{vol.Optional(ATTR_ACTIVITY): cv.string}
|
||||||
|
@ -103,12 +106,22 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool:
|
||||||
{
|
{
|
||||||
vol.Optional(ATTR_DEVICE): cv.string,
|
vol.Optional(ATTR_DEVICE): cv.string,
|
||||||
vol.Optional(ATTR_COMMAND): vol.All(cv.ensure_list, [cv.string]),
|
vol.Optional(ATTR_COMMAND): vol.All(cv.ensure_list, [cv.string]),
|
||||||
|
vol.Optional(ATTR_COMMAND_TYPE): cv.string,
|
||||||
vol.Optional(ATTR_ALTERNATIVE): cv.boolean,
|
vol.Optional(ATTR_ALTERNATIVE): cv.boolean,
|
||||||
vol.Optional(ATTR_TIMEOUT): cv.positive_int,
|
vol.Optional(ATTR_TIMEOUT): cv.positive_int,
|
||||||
},
|
},
|
||||||
"async_learn_command",
|
"async_learn_command",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
component.async_register_entity_service(
|
||||||
|
SERVICE_DELETE_COMMAND,
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_COMMAND): vol.All(cv.ensure_list, [cv.string]),
|
||||||
|
vol.Optional(ATTR_DEVICE): cv.string,
|
||||||
|
},
|
||||||
|
"async_delete_command",
|
||||||
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,6 +163,17 @@ class RemoteEntity(ToggleEntity):
|
||||||
assert self.hass is not None
|
assert self.hass is not None
|
||||||
await self.hass.async_add_executor_job(ft.partial(self.learn_command, **kwargs))
|
await self.hass.async_add_executor_job(ft.partial(self.learn_command, **kwargs))
|
||||||
|
|
||||||
|
def delete_command(self, **kwargs: Any) -> None:
|
||||||
|
"""Delete commands from the database."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def async_delete_command(self, **kwargs: Any) -> None:
|
||||||
|
"""Delete commands from the database."""
|
||||||
|
assert self.hass is not None
|
||||||
|
await self.hass.async_add_executor_job(
|
||||||
|
ft.partial(self.delete_command, **kwargs)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RemoteDevice(RemoteEntity):
|
class RemoteDevice(RemoteEntity):
|
||||||
"""Representation of a remote (for backwards compatibility)."""
|
"""Representation of a remote (for backwards compatibility)."""
|
||||||
|
|
|
@ -58,9 +58,25 @@ learn_command:
|
||||||
command:
|
command:
|
||||||
description: A single command or a list of commands to learn.
|
description: A single command or a list of commands to learn.
|
||||||
example: "Turn on"
|
example: "Turn on"
|
||||||
|
command_type:
|
||||||
|
description: The type of command to be learned.
|
||||||
|
example: "rf"
|
||||||
alternative:
|
alternative:
|
||||||
description: If code must be stored as alternative (useful for discrete remotes).
|
description: If code must be stored as alternative (useful for discrete remotes).
|
||||||
example: "True"
|
example: "True"
|
||||||
timeout:
|
timeout:
|
||||||
description: Timeout, in seconds, for the command to be learned.
|
description: Timeout, in seconds, for the command to be learned.
|
||||||
example: "30"
|
example: "30"
|
||||||
|
|
||||||
|
delete_command:
|
||||||
|
description: Deletes a command or a list of commands from the database.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of the remote entities holding the database.
|
||||||
|
example: "remote.bedroom"
|
||||||
|
device:
|
||||||
|
description: Name of the device from which commands will be deleted.
|
||||||
|
example: "television"
|
||||||
|
command:
|
||||||
|
description: A single command or a list of commands to delete.
|
||||||
|
example: "Mute"
|
||||||
|
|
|
@ -7,11 +7,13 @@ from homeassistant.components.remote import (
|
||||||
ATTR_ACTIVITY,
|
ATTR_ACTIVITY,
|
||||||
ATTR_ALTERNATIVE,
|
ATTR_ALTERNATIVE,
|
||||||
ATTR_COMMAND,
|
ATTR_COMMAND,
|
||||||
|
ATTR_COMMAND_TYPE,
|
||||||
ATTR_DELAY_SECS,
|
ATTR_DELAY_SECS,
|
||||||
ATTR_DEVICE,
|
ATTR_DEVICE,
|
||||||
ATTR_NUM_REPEATS,
|
ATTR_NUM_REPEATS,
|
||||||
ATTR_TIMEOUT,
|
ATTR_TIMEOUT,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
SERVICE_DELETE_COMMAND,
|
||||||
SERVICE_LEARN_COMMAND,
|
SERVICE_LEARN_COMMAND,
|
||||||
SERVICE_SEND_COMMAND,
|
SERVICE_SEND_COMMAND,
|
||||||
)
|
)
|
||||||
|
@ -81,6 +83,7 @@ def learn_command(
|
||||||
device=None,
|
device=None,
|
||||||
command=None,
|
command=None,
|
||||||
alternative=None,
|
alternative=None,
|
||||||
|
command_type=None,
|
||||||
timeout=None,
|
timeout=None,
|
||||||
):
|
):
|
||||||
"""Learn a command from a device."""
|
"""Learn a command from a device."""
|
||||||
|
@ -94,6 +97,9 @@ def learn_command(
|
||||||
if command:
|
if command:
|
||||||
data[ATTR_COMMAND] = command
|
data[ATTR_COMMAND] = command
|
||||||
|
|
||||||
|
if command_type:
|
||||||
|
data[ATTR_COMMAND_TYPE] = command_type
|
||||||
|
|
||||||
if alternative:
|
if alternative:
|
||||||
data[ATTR_ALTERNATIVE] = alternative
|
data[ATTR_ALTERNATIVE] = alternative
|
||||||
|
|
||||||
|
@ -101,3 +107,24 @@ def learn_command(
|
||||||
data[ATTR_TIMEOUT] = timeout
|
data[ATTR_TIMEOUT] = timeout
|
||||||
|
|
||||||
hass.services.call(DOMAIN, SERVICE_LEARN_COMMAND, data)
|
hass.services.call(DOMAIN, SERVICE_LEARN_COMMAND, data)
|
||||||
|
|
||||||
|
|
||||||
|
@bind_hass
|
||||||
|
def delete_command(
|
||||||
|
hass,
|
||||||
|
entity_id=ENTITY_MATCH_ALL,
|
||||||
|
device=None,
|
||||||
|
command=None,
|
||||||
|
):
|
||||||
|
"""Delete commands from the database."""
|
||||||
|
data = {}
|
||||||
|
if entity_id:
|
||||||
|
data[ATTR_ENTITY_ID] = entity_id
|
||||||
|
|
||||||
|
if device:
|
||||||
|
data[ATTR_DEVICE] = device
|
||||||
|
|
||||||
|
if command:
|
||||||
|
data[ATTR_COMMAND] = command
|
||||||
|
|
||||||
|
hass.services.call(DOMAIN, SERVICE_DELETE_COMMAND, data)
|
||||||
|
|
|
@ -19,6 +19,7 @@ from tests.components.remote import common
|
||||||
TEST_PLATFORM = {remote.DOMAIN: {CONF_PLATFORM: "test"}}
|
TEST_PLATFORM = {remote.DOMAIN: {CONF_PLATFORM: "test"}}
|
||||||
SERVICE_SEND_COMMAND = "send_command"
|
SERVICE_SEND_COMMAND = "send_command"
|
||||||
SERVICE_LEARN_COMMAND = "learn_command"
|
SERVICE_LEARN_COMMAND = "learn_command"
|
||||||
|
SERVICE_DELETE_COMMAND = "delete_command"
|
||||||
|
|
||||||
|
|
||||||
class TestRemote(unittest.TestCase):
|
class TestRemote(unittest.TestCase):
|
||||||
|
@ -101,6 +102,7 @@ class TestRemote(unittest.TestCase):
|
||||||
entity_id="entity_id_val",
|
entity_id="entity_id_val",
|
||||||
device="test_device",
|
device="test_device",
|
||||||
command=["test_command"],
|
command=["test_command"],
|
||||||
|
command_type="rf",
|
||||||
alternative=True,
|
alternative=True,
|
||||||
timeout=20,
|
timeout=20,
|
||||||
)
|
)
|
||||||
|
@ -114,6 +116,28 @@ class TestRemote(unittest.TestCase):
|
||||||
assert call.service == SERVICE_LEARN_COMMAND
|
assert call.service == SERVICE_LEARN_COMMAND
|
||||||
assert call.data[ATTR_ENTITY_ID] == "entity_id_val"
|
assert call.data[ATTR_ENTITY_ID] == "entity_id_val"
|
||||||
|
|
||||||
|
def test_delete_command(self):
|
||||||
|
"""Test delete_command."""
|
||||||
|
delete_command_calls = mock_service(
|
||||||
|
self.hass, remote.DOMAIN, SERVICE_DELETE_COMMAND
|
||||||
|
)
|
||||||
|
|
||||||
|
common.delete_command(
|
||||||
|
self.hass,
|
||||||
|
entity_id="entity_id_val",
|
||||||
|
device="test_device",
|
||||||
|
command=["test_command"],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
assert len(delete_command_calls) == 1
|
||||||
|
call = delete_command_calls[-1]
|
||||||
|
|
||||||
|
assert call.domain == remote.DOMAIN
|
||||||
|
assert call.service == SERVICE_DELETE_COMMAND
|
||||||
|
assert call.data[ATTR_ENTITY_ID] == "entity_id_val"
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_base_class(caplog):
|
def test_deprecated_base_class(caplog):
|
||||||
"""Test deprecated base class."""
|
"""Test deprecated base class."""
|
||||||
|
|
Loading…
Add table
Reference in a new issue