Add Dynalite service to request the channel level (#38735)

* added service to request the channel level

* cleanup

* Update homeassistant/components/dynalite/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/dynalite/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update services.yaml

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Ziv 2020-08-11 19:33:16 +03:00 committed by GitHub
parent f31a580caf
commit 6a8378bec0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 22 deletions

View File

@ -1,7 +1,7 @@
"""Support for the Dynalite networks.""" """Support for the Dynalite networks."""
import asyncio import asyncio
from typing import Any, Dict, List, Union from typing import Any, Dict, Union
import voluptuous as vol import voluptuous as vol
@ -49,6 +49,8 @@ from .const import (
DOMAIN, DOMAIN,
ENTITY_PLATFORMS, ENTITY_PLATFORMS,
LOGGER, LOGGER,
SERVICE_REQUEST_AREA_PRESET,
SERVICE_REQUEST_CHANNEL_LEVEL,
) )
@ -201,27 +203,27 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
) )
) )
def get_bridges(host: str) -> List[DynaliteBridge]: async def dynalite_service(service_call: ServiceCall):
result = [] data = service_call.data
for entry_id in hass.data[DOMAIN]: host = data.get(ATTR_HOST, "")
cur_bridge = hass.data[DOMAIN][entry_id] bridges = []
for cur_bridge in hass.data[DOMAIN].values():
if not host or cur_bridge.host == host: if not host or cur_bridge.host == host:
result.append(cur_bridge) bridges.append(cur_bridge)
return result
async def request_area_preset_service(service_call: ServiceCall):
host = service_call.data.get(ATTR_HOST, "")
bridges = get_bridges(host)
LOGGER.debug("Selected bridged for service call: %s", bridges) LOGGER.debug("Selected bridged for service call: %s", bridges)
area = service_call.data[ATTR_AREA] if service_call.service == SERVICE_REQUEST_AREA_PRESET:
channel = service_call.data.get(ATTR_CHANNEL) bridge_attr = "request_area_preset"
elif service_call.service == SERVICE_REQUEST_CHANNEL_LEVEL:
bridge_attr = "request_channel_level"
for bridge in bridges: for bridge in bridges:
bridge.dynalite_devices.request_area_preset(area, channel) getattr(bridge.dynalite_devices, bridge_attr)(
data[ATTR_AREA], data.get(ATTR_CHANNEL)
)
hass.services.async_register( hass.services.async_register(
DOMAIN, DOMAIN,
"request_area_preset", SERVICE_REQUEST_AREA_PRESET,
request_area_preset_service, dynalite_service,
vol.Schema( vol.Schema(
{ {
vol.Optional(ATTR_HOST): cv.string, vol.Optional(ATTR_HOST): cv.string,
@ -231,6 +233,19 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
), ),
) )
hass.services.async_register(
DOMAIN,
SERVICE_REQUEST_CHANNEL_LEVEL,
dynalite_service,
vol.Schema(
{
vol.Optional(ATTR_HOST): cv.string,
vol.Required(ATTR_AREA): int,
vol.Required(ATTR_CHANNEL): int,
}
),
)
return True return True

View File

@ -55,3 +55,6 @@ ATTR_CHANNEL = "channel"
ATTR_HOST = "host" ATTR_HOST = "host"
ATTR_PACKET = "packet" ATTR_PACKET = "packet"
ATTR_PRESET = "preset" ATTR_PRESET = "preset"
SERVICE_REQUEST_AREA_PRESET = "request_area_preset"
SERVICE_REQUEST_CHANNEL_LEVEL = "request_channel_level"

View File

@ -11,3 +11,16 @@ request_area_preset:
description: "Channel to request the preset to be reported from. Default is channel 1" description: "Channel to request the preset to be reported from. Default is channel 1"
example: 1 example: 1
request_channel_level:
description: "Requests Dynalite to report the level of a specific channel."
fields:
host:
description: "Host gateway IP to send to or all configured gateways if not specified."
example: "192.168.0.101"
area:
description: "Area for the requested channel"
example: 2
channel:
description: "Channel to request the level for."
example: 1

View File

@ -1,6 +1,9 @@
"""Test Dynalite __init__.""" """Test Dynalite __init__."""
import pytest
from voluptuous import MultipleInvalid
import homeassistant.components.dynalite.const as dynalite import homeassistant.components.dynalite.const as dynalite
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_ROOM from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_ROOM
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -93,12 +96,8 @@ async def test_service_request_area_preset(hass):
{ {
dynalite.DOMAIN: { dynalite.DOMAIN: {
dynalite.CONF_BRIDGES: [ dynalite.CONF_BRIDGES: [
{ {CONF_HOST: "1.2.3.4"},
CONF_HOST: "1.2.3.4", {CONF_HOST: "5.6.7.8"},
CONF_PORT: 1234,
dynalite.CONF_AREA: {"7": {CONF_NAME: "test"}},
},
{CONF_HOST: "5.6.7.8", CONF_PORT: 5678},
] ]
} }
}, },
@ -144,6 +143,53 @@ async def test_service_request_area_preset(hass):
mock_req_area_pres.assert_called_once_with(7, 1) mock_req_area_pres.assert_called_once_with(7, 1)
async def test_service_request_channel_level(hass):
"""Test requesting the level of a channel via service call."""
with patch(
"homeassistant.components.dynalite.bridge.DynaliteDevices.async_setup",
return_value=True,
), patch(
"dynalite_devices_lib.dynalite.Dynalite.request_channel_level",
return_value=True,
) as mock_req_chan_lvl:
assert await async_setup_component(
hass,
dynalite.DOMAIN,
{
dynalite.DOMAIN: {
dynalite.CONF_BRIDGES: [
{
CONF_HOST: "1.2.3.4",
dynalite.CONF_AREA: {"7": {CONF_NAME: "test"}},
},
{CONF_HOST: "5.6.7.8"},
]
}
},
)
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(dynalite.DOMAIN)) == 2
await hass.services.async_call(
dynalite.DOMAIN,
"request_channel_level",
{"host": "1.2.3.4", "area": 2, "channel": 3},
)
await hass.async_block_till_done()
mock_req_chan_lvl.assert_called_once_with(2, 3)
mock_req_chan_lvl.reset_mock()
with pytest.raises(MultipleInvalid):
await hass.services.async_call(
dynalite.DOMAIN, "request_channel_level", {"area": 3},
)
await hass.async_block_till_done()
mock_req_chan_lvl.assert_not_called()
await hass.services.async_call(
dynalite.DOMAIN, "request_channel_level", {"area": 4, "channel": 5},
)
await hass.async_block_till_done()
assert mock_req_chan_lvl.mock_calls == [call(4, 5), call(4, 5)]
async def test_async_setup_bad_config1(hass): async def test_async_setup_bad_config1(hass):
"""Test a successful with bad config on templates.""" """Test a successful with bad config on templates."""
with patch( with patch(