-
-
Notifications
You must be signed in to change notification settings - Fork 239
Closed
Description
Hi, thanks for the cool product.
On my dd-wrt router, the broadcast socket does not work without specifying the network interface name. Please add to the code possibility to specify the network interface name during the discovery process.
I am too lazy to create a full pull-request, so, just a code:
async def discover(*, target="255.255.255.255",
on_discovered=None,
timeout=5,
discovery_packets=3,
return_raw=False,
interface=None) -> Mapping[str, Union[SmartDevice, Dict]]:
loop = asyncio.get_event_loop()
transport, protocol = await loop.create_datagram_endpoint(
lambda: __DiscoverProtocol(
target=target,
on_discovered=on_discovered,
timeout=timeout,
discovery_packets=discovery_packets,
interface=interface
),
local_addr=("0.0.0.0", 0),
)
protocol = cast(__DiscoverProtocol, protocol)
try:
await asyncio.sleep(5)
finally:
transport.close()
if return_raw:
return protocol.discovered_devices_raw
return protocol.discovered_devices
class _DiscoverProtocol(asyncio.DatagramProtocol):
discovered_devices: Dict[str, SmartDevice]
discovered_devices_raw: Dict[str, Dict]
def __init__(
self,
*,
on_discovered: OnDiscoveredCallable = None,
target: str = "255.255.255.255",
timeout: int = 5,
discovery_packets: int = 3,
interface: bytes = b""
):
self.transport = None
self.tries = discovery_packets
self.timeout = timeout
self.interface = interface
self.on_discovered = on_discovered
self.protocol = TPLinkSmartHomeProtocol()
self.target = (target, Discover.DISCOVERY_PORT)
self.discovered_devices = {}
self.discovered_devices_raw = {}
def connection_made(self, transport) -> None:
"""Set socket options for broadcasting."""
self.transport = transport
sock = transport.get_extra_info("socket")
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if self.interface is not None and len(self.interface) > 0:
sock.setsockopt(socket.SOL_SOCKET, 25, self.interface)
self.do_discover()Usage on my dd-wrt router:
devices = asyncio.run(Discover.discover(interface=b"br0"))Metadata
Metadata
Assignees
Labels
No labels