From f1d5f95f7c1ecefe2463db294e9f7b9b1755b42c Mon Sep 17 00:00:00 2001 From: Janitha Karunaratne Date: Wed, 10 Jun 2020 17:05:24 -0500 Subject: [PATCH] Allow specifying port for wake_on_lan (#36510) --- .../components/wake_on_lan/__init__.py | 13 +++++-- .../components/wake_on_lan/services.yaml | 9 +++-- .../components/wake_on_lan/switch.py | 39 +++++++++++++++++-- homeassistant/const.py | 1 + tests/components/wake_on_lan/test_init.py | 4 +- tests/components/wake_on_lan/test_switch.py | 1 + 6 files changed, 56 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/wake_on_lan/__init__.py b/homeassistant/components/wake_on_lan/__init__.py index d5b8f92a9bc..1600f70a15f 100644 --- a/homeassistant/components/wake_on_lan/__init__.py +++ b/homeassistant/components/wake_on_lan/__init__.py @@ -5,7 +5,7 @@ import logging import voluptuous as vol import wakeonlan -from homeassistant.const import CONF_BROADCAST_ADDRESS, CONF_MAC +from homeassistant.const import CONF_BROADCAST_ADDRESS, CONF_BROADCAST_PORT, CONF_MAC import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) @@ -15,7 +15,11 @@ DOMAIN = "wake_on_lan" SERVICE_SEND_MAGIC_PACKET = "send_magic_packet" WAKE_ON_LAN_SEND_MAGIC_PACKET_SCHEMA = vol.Schema( - {vol.Required(CONF_MAC): cv.string, vol.Optional(CONF_BROADCAST_ADDRESS): cv.string} + { + vol.Required(CONF_MAC): cv.string, + vol.Optional(CONF_BROADCAST_ADDRESS): cv.string, + vol.Optional(CONF_BROADCAST_PORT): cv.port, + } ) @@ -26,10 +30,12 @@ async def async_setup(hass, config): """Send magic packet to wake up a device.""" mac_address = call.data.get(CONF_MAC) broadcast_address = call.data.get(CONF_BROADCAST_ADDRESS) + broadcast_port = call.data.get(CONF_BROADCAST_PORT) _LOGGER.info( - "Send magic packet to mac %s (broadcast: %s)", + "Send magic packet to mac %s (broadcast: %s, port: %s)", mac_address, broadcast_address, + broadcast_port, ) if broadcast_address is not None: await hass.async_add_job( @@ -37,6 +43,7 @@ async def async_setup(hass, config): wakeonlan.send_magic_packet, mac_address, ip_address=broadcast_address, + port=broadcast_port, ) ) else: diff --git a/homeassistant/components/wake_on_lan/services.yaml b/homeassistant/components/wake_on_lan/services.yaml index 915dd2bce96..54ce72c9432 100644 --- a/homeassistant/components/wake_on_lan/services.yaml +++ b/homeassistant/components/wake_on_lan/services.yaml @@ -1,9 +1,12 @@ send_magic_packet: description: Send a 'magic packet' to wake up a device with 'Wake-On-LAN' capabilities. fields: - broadcast_address: - description: Optional broadcast IP where to send the magic packet. - example: 192.168.255.255 mac: description: MAC address of the device to wake up. example: "aa:bb:cc:dd:ee:ff" + broadcast_address: + description: Optional broadcast IP where to send the magic packet. + example: 192.168.255.255 + broadcast_port: + description: Optional port where to send the magic packet. + example: 9 diff --git a/homeassistant/components/wake_on_lan/switch.py b/homeassistant/components/wake_on_lan/switch.py index e3af8f146f1..8f26e19d2e0 100644 --- a/homeassistant/components/wake_on_lan/switch.py +++ b/homeassistant/components/wake_on_lan/switch.py @@ -7,7 +7,13 @@ import voluptuous as vol import wakeonlan from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity -from homeassistant.const import CONF_BROADCAST_ADDRESS, CONF_HOST, CONF_MAC, CONF_NAME +from homeassistant.const import ( + CONF_BROADCAST_ADDRESS, + CONF_BROADCAST_PORT, + CONF_HOST, + CONF_MAC, + CONF_NAME, +) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.script import Script @@ -22,6 +28,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_MAC): cv.string, vol.Optional(CONF_BROADCAST_ADDRESS): cv.string, + vol.Optional(CONF_BROADCAST_PORT): cv.port, vol.Optional(CONF_HOST): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_OFF_ACTION): cv.SCRIPT_SCHEMA, @@ -32,26 +39,48 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a wake on lan switch.""" broadcast_address = config.get(CONF_BROADCAST_ADDRESS) + broadcast_port = config.get(CONF_BROADCAST_PORT) host = config.get(CONF_HOST) mac_address = config[CONF_MAC] name = config[CONF_NAME] off_action = config.get(CONF_OFF_ACTION) add_entities( - [WolSwitch(hass, name, host, mac_address, off_action, broadcast_address)], True + [ + WolSwitch( + hass, + name, + host, + mac_address, + off_action, + broadcast_address, + broadcast_port, + ) + ], + True, ) class WolSwitch(SwitchEntity): """Representation of a wake on lan switch.""" - def __init__(self, hass, name, host, mac_address, off_action, broadcast_address): + def __init__( + self, + hass, + name, + host, + mac_address, + off_action, + broadcast_address, + broadcast_port, + ): """Initialize the WOL switch.""" self._hass = hass self._name = name self._host = host self._mac_address = mac_address self._broadcast_address = broadcast_address + self._broadcast_port = broadcast_port self._off_script = Script(hass, off_action) if off_action else None self._state = False @@ -69,7 +98,9 @@ class WolSwitch(SwitchEntity): """Turn the device on.""" if self._broadcast_address: wakeonlan.send_magic_packet( - self._mac_address, ip_address=self._broadcast_address + self._mac_address, + ip_address=self._broadcast_address, + port=self._broadcast_port, ) else: wakeonlan.send_magic_packet(self._mac_address) diff --git a/homeassistant/const.py b/homeassistant/const.py index 0a9c755cc3a..578c5215ed3 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -46,6 +46,7 @@ CONF_BINARY_SENSORS = "binary_sensors" CONF_BLACKLIST = "blacklist" CONF_BRIGHTNESS = "brightness" CONF_BROADCAST_ADDRESS = "broadcast_address" +CONF_BROADCAST_PORT = "broadcast_port" CONF_CLIENT_ID = "client_id" CONF_CLIENT_SECRET = "client_secret" CONF_CODE = "code" diff --git a/tests/components/wake_on_lan/test_init.py b/tests/components/wake_on_lan/test_init.py index 6eb7afb29f4..331f66b03d8 100644 --- a/tests/components/wake_on_lan/test_init.py +++ b/tests/components/wake_on_lan/test_init.py @@ -13,18 +13,20 @@ async def test_send_magic_packet(hass): with patch("homeassistant.components.wake_on_lan.wakeonlan") as mocked_wakeonlan: mac = "aa:bb:cc:dd:ee:ff" bc_ip = "192.168.255.255" + bc_port = 999 await async_setup_component(hass, DOMAIN, {}) await hass.services.async_call( DOMAIN, SERVICE_SEND_MAGIC_PACKET, - {"mac": mac, "broadcast_address": bc_ip}, + {"mac": mac, "broadcast_address": bc_ip, "broadcast_port": bc_port}, blocking=True, ) assert len(mocked_wakeonlan.mock_calls) == 1 assert mocked_wakeonlan.mock_calls[-1][1][0] == mac assert mocked_wakeonlan.mock_calls[-1][2]["ip_address"] == bc_ip + assert mocked_wakeonlan.mock_calls[-1][2]["port"] == bc_port with pytest.raises(vol.Invalid): await hass.services.async_call( diff --git a/tests/components/wake_on_lan/test_switch.py b/tests/components/wake_on_lan/test_switch.py index 6db8018593d..ce5dbca9585 100644 --- a/tests/components/wake_on_lan/test_switch.py +++ b/tests/components/wake_on_lan/test_switch.py @@ -126,6 +126,7 @@ class TestWolSwitch(unittest.TestCase): "platform": "wake_on_lan", "mac": "00-01-02-03-04-05", "broadcast_address": "255.255.255.255", + "broadcast_port": 999, } }, )