From cb63a9d7e17af0f243cbc34458b1452098846168 Mon Sep 17 00:00:00 2001 From: Jay Newstrom <jaynewstrom@gmail.com> Date: Sun, 17 Nov 2019 06:17:22 -0600 Subject: [PATCH] Add broadcast address for WOL and samsungtv (#28819) * Add broadcast address for WOL and samsungtv * Fix style * Fix tests, and add new test for new functionality * Fix code style --- .../components/samsungtv/media_player.py | 14 +++++++-- .../components/samsungtv/test_media_player.py | 31 ++++++++++++++++++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/samsungtv/media_player.py b/homeassistant/components/samsungtv/media_player.py index 65805235f3f..1262c3d7d36 100644 --- a/homeassistant/components/samsungtv/media_player.py +++ b/homeassistant/components/samsungtv/media_player.py @@ -26,6 +26,7 @@ from homeassistant.components.media_player.const import ( SUPPORT_VOLUME_STEP, ) from homeassistant.const import ( + CONF_BROADCAST_ADDRESS, CONF_HOST, CONF_MAC, CONF_NAME, @@ -41,6 +42,7 @@ from .const import LOGGER DEFAULT_NAME = "Samsung TV Remote" DEFAULT_TIMEOUT = 1 +DEFAULT_BROADCAST_ADDRESS = "255.255.255.255" KEY_PRESS_TIMEOUT = 1.2 KNOWN_DEVICES_KEY = "samsungtv_known_devices" @@ -65,6 +67,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_PORT): cv.port, vol.Optional(CONF_MAC): cv.string, + vol.Optional( + CONF_BROADCAST_ADDRESS, default=DEFAULT_BROADCAST_ADDRESS + ): cv.string, vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int, } ) @@ -84,6 +89,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): port = config.get(CONF_PORT) name = config.get(CONF_NAME) mac = config.get(CONF_MAC) + broadcast = config.get(CONF_BROADCAST_ADDRESS) timeout = config.get(CONF_TIMEOUT) elif discovery_info is not None: tv_name = discovery_info.get("name") @@ -95,6 +101,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): port = None timeout = DEFAULT_TIMEOUT mac = None + broadcast = DEFAULT_BROADCAST_ADDRESS uuid = discovery_info.get("udn") if uuid and uuid.startswith("uuid:"): uuid = uuid[len("uuid:") :] @@ -104,7 +111,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): ip_addr = socket.gethostbyname(host) if ip_addr not in known_devices: known_devices.add(ip_addr) - add_entities([SamsungTVDevice(host, port, name, timeout, mac, uuid)]) + add_entities([SamsungTVDevice(host, port, name, timeout, mac, broadcast, uuid)]) LOGGER.info("Samsung TV %s added as '%s'", host, name) else: LOGGER.info("Ignoring duplicate Samsung TV %s", host) @@ -113,12 +120,13 @@ def setup_platform(hass, config, add_entities, discovery_info=None): class SamsungTVDevice(MediaPlayerDevice): """Representation of a Samsung TV.""" - def __init__(self, host, port, name, timeout, mac, uuid): + def __init__(self, host, port, name, timeout, mac, broadcast, uuid): """Initialize the Samsung device.""" # Save a reference to the imported classes self._name = name self._mac = mac + self._broadcast = broadcast self._uuid = uuid # Assume that the TV is not muted self._muted = False @@ -339,7 +347,7 @@ class SamsungTVDevice(MediaPlayerDevice): def turn_on(self): """Turn the media player on.""" if self._mac: - wakeonlan.send_magic_packet(self._mac) + wakeonlan.send_magic_packet(self._mac, ip_address=self._broadcast) else: self.send_key("KEY_POWERON") diff --git a/tests/components/samsungtv/test_media_player.py b/tests/components/samsungtv/test_media_player.py index 3409e55a49c..8f6014463f5 100644 --- a/tests/components/samsungtv/test_media_player.py +++ b/tests/components/samsungtv/test_media_player.py @@ -32,6 +32,7 @@ from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, ATTR_SUPPORTED_FEATURES, + CONF_BROADCAST_ADDRESS, CONF_HOST, CONF_MAC, CONF_NAME, @@ -67,6 +68,19 @@ MOCK_CONFIG = { } } +ENTITY_ID_BROADCAST = f"{DOMAIN}.fake_broadcast" +MOCK_CONFIG_BROADCAST = { + DOMAIN: { + CONF_PLATFORM: SAMSUNGTV_DOMAIN, + CONF_HOST: "fake_broadcast", + CONF_NAME: "fake_broadcast", + CONF_PORT: 8001, + CONF_TIMEOUT: 10, + CONF_MAC: "38:f9:d3:82:b4:f1", + CONF_BROADCAST_ADDRESS: "192.168.5.255", + } +} + ENTITY_ID_NOMAC = f"{DOMAIN}.fake_nomac" MOCK_CONFIG_NOMAC = { DOMAIN: { @@ -565,7 +579,22 @@ async def test_turn_on_with_mac(hass, remote, wakeonlan): ) # key and update called assert wakeonlan.send_magic_packet.call_count == 1 - assert wakeonlan.send_magic_packet.call_args_list == [call("38:f9:d3:82:b4:f1")] + assert wakeonlan.send_magic_packet.call_args_list == [ + call("38:f9:d3:82:b4:f1", ip_address="255.255.255.255") + ] + + +async def test_turn_on_with_mac_and_broadcast(hass, remote, wakeonlan): + """Test turn on.""" + await setup_samsungtv(hass, MOCK_CONFIG_BROADCAST) + assert await hass.services.async_call( + DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID_BROADCAST}, True + ) + # key and update called + assert wakeonlan.send_magic_packet.call_count == 1 + assert wakeonlan.send_magic_packet.call_args_list == [ + call("38:f9:d3:82:b4:f1", ip_address="192.168.5.255") + ] async def test_turn_on_without_mac(hass, remote): -- GitLab