Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions kasa/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def __init__(
port: Optional[int] = None,
discovered_event: Optional[asyncio.Event] = None,
credentials: Optional[Credentials] = None,
):
timeout: Optional[int] = None,
) -> None:
self.transport = None
self.discovery_packets = discovery_packets
self.interface = interface
Expand All @@ -61,6 +62,7 @@ def __init__(
self.on_unsupported = on_unsupported
self.discovered_event = discovered_event
self.credentials = credentials
self.timeout = timeout

def connection_made(self, transport) -> None:
"""Set socket options for broadcasting."""
Expand Down Expand Up @@ -124,7 +126,9 @@ def datagram_received(self, data, addr) -> None:
self.discovered_event.set()
return

device = device_class(ip, port=port, credentials=self.credentials)
device = device_class(
ip, port=port, credentials=self.credentials, timeout=self.timeout
)
device.update_from_discover_info(info)

self.discovered_devices[ip] = device
Expand Down Expand Up @@ -226,6 +230,7 @@ async def discover(
interface=interface,
on_unsupported=on_unsupported,
credentials=credentials,
timeout=timeout,
),
local_addr=("0.0.0.0", 0),
)
Expand Down Expand Up @@ -259,7 +264,11 @@ async def discover_single(
event = asyncio.Event()
transport, protocol = await loop.create_datagram_endpoint(
lambda: _DiscoverProtocol(
target=host, port=port, discovered_event=event, credentials=credentials
target=host,
port=port,
discovered_event=event,
credentials=credentials,
timeout=timeout,
),
local_addr=("0.0.0.0", 0),
)
Expand Down
9 changes: 5 additions & 4 deletions kasa/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@ class TPLinkSmartHomeProtocol:
DEFAULT_TIMEOUT = 5
BLOCK_SIZE = 4

def __init__(self, host: str, *, port: Optional[int] = None) -> None:
def __init__(
self, host: str, *, port: Optional[int] = None, timeout: Optional[int] = None
) -> None:
"""Create a protocol object."""
self.host = host
self.port = port or TPLinkSmartHomeProtocol.DEFAULT_PORT
self.reader: Optional[asyncio.StreamReader] = None
self.writer: Optional[asyncio.StreamWriter] = None
self.query_lock: Optional[asyncio.Lock] = None
self.loop: Optional[asyncio.AbstractEventLoop] = None
self.timeout = timeout or TPLinkSmartHomeProtocol.DEFAULT_TIMEOUT

def _detect_event_loop_change(self) -> None:
"""Check if this object has been reused betwen event loops."""
Expand Down Expand Up @@ -73,10 +76,8 @@ async def query(self, request: Union[str, Dict], retry_count: int = 3) -> Dict:
request = json_dumps(request)
assert isinstance(request, str)

timeout = TPLinkSmartHomeProtocol.DEFAULT_TIMEOUT

async with self.query_lock:
return await self._query(request, retry_count, timeout)
return await self._query(request, retry_count, self.timeout)

async def _connect(self, timeout: int) -> None:
"""Try to connect or reconnect to the device."""
Expand Down
7 changes: 4 additions & 3 deletions kasa/smartbulb.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ def __init__(
host: str,
*,
port: Optional[int] = None,
credentials: Optional[Credentials] = None
credentials: Optional[Credentials] = None,
timeout: Optional[int] = None,
) -> None:
super().__init__(host=host, port=port, credentials=credentials)
super().__init__(host=host, port=port, credentials=credentials, timeout=timeout)
self._device_type = DeviceType.Bulb
self.add_module("schedule", Schedule(self, "smartlife.iot.common.schedule"))
self.add_module("usage", Usage(self, "smartlife.iot.common.schedule"))
Expand Down Expand Up @@ -372,7 +373,7 @@ async def set_hsv(
saturation: int,
value: Optional[int] = None,
*,
transition: Optional[int] = None
transition: Optional[int] = None,
) -> Dict:
"""Set new HSV.

Expand Down
3 changes: 2 additions & 1 deletion kasa/smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ def __init__(
*,
port: Optional[int] = None,
credentials: Optional[Credentials] = None,
timeout: Optional[int] = None,
) -> None:
"""Create a new SmartDevice instance.

Expand All @@ -203,7 +204,7 @@ def __init__(
self.host = host
self.port = port

self.protocol = TPLinkSmartHomeProtocol(host, port=port)
self.protocol = TPLinkSmartHomeProtocol(host, port=port, timeout=timeout)
self.credentials = credentials
_LOGGER.debug("Initializing %s of type %s", self.host, type(self))
self._device_type = DeviceType.Unknown
Expand Down
3 changes: 2 additions & 1 deletion kasa/smartdimmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ def __init__(
*,
port: Optional[int] = None,
credentials: Optional[Credentials] = None,
timeout: Optional[int] = None,
) -> None:
super().__init__(host, port=port, credentials=credentials)
super().__init__(host, port=port, credentials=credentials, timeout=timeout)
self._device_type = DeviceType.Dimmer
# TODO: need to be verified if it's okay to call these on HS220 w/o these
# TODO: need to be figured out what's the best approach to detect support for these
Expand Down
3 changes: 2 additions & 1 deletion kasa/smartlightstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ def __init__(
*,
port: Optional[int] = None,
credentials: Optional[Credentials] = None,
timeout: Optional[int] = None,
) -> None:
super().__init__(host, port=port, credentials=credentials)
super().__init__(host, port=port, credentials=credentials, timeout=timeout)
self._device_type = DeviceType.LightStrip

@property # type: ignore
Expand Down
5 changes: 3 additions & 2 deletions kasa/smartplug.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ def __init__(
host: str,
*,
port: Optional[int] = None,
credentials: Optional[Credentials] = None
credentials: Optional[Credentials] = None,
timeout: Optional[int] = None,
) -> None:
super().__init__(host, port=port, credentials=credentials)
super().__init__(host, port=port, credentials=credentials, timeout=timeout)
self._device_type = DeviceType.Plug
self.add_module("schedule", Schedule(self, "schedule"))
self.add_module("usage", Usage(self, "schedule"))
Expand Down
3 changes: 2 additions & 1 deletion kasa/smartstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ def __init__(
*,
port: Optional[int] = None,
credentials: Optional[Credentials] = None,
timeout: Optional[int] = None,
) -> None:
super().__init__(host=host, port=port, credentials=credentials)
super().__init__(host=host, port=port, credentials=credentials, timeout=timeout)
self.emeter_type = "emeter"
self._device_type = DeviceType.Strip
self.add_module("antitheft", Antitheft(self, "anti_theft"))
Expand Down
2 changes: 1 addition & 1 deletion kasa/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ async def _update_and_close(d):


async def _discover_update_and_close(ip):
d = await Discover.discover_single(ip)
d = await Discover.discover_single(ip, timeout=10)
return await _update_and_close(d)


Expand Down
6 changes: 6 additions & 0 deletions kasa/tests/test_smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,9 @@ async def test_modules_preserved(dev: SmartDevice):
dev._last_update["some_module_not_being_updated"] = "should_be_kept"
await dev.update()
assert dev._last_update["some_module_not_being_updated"] == "should_be_kept"


async def test_create_smart_device_with_timeout():
"""Make sure timeout is passed to the protocol."""
dev = SmartDevice(host="127.0.0.1", timeout=100)
assert dev.protocol.timeout == 100