diff --git a/pyfritzhome/fritzhome.py b/pyfritzhome/fritzhome.py index 38916ca..1ca8442 100644 --- a/pyfritzhome/fritzhome.py +++ b/pyfritzhome/fritzhome.py @@ -37,6 +37,7 @@ def __init__(self, host, user, password, ssl_verify=True): self._session = Session() self._ssl_verify = ssl_verify self._has_getdeviceinfos = True + self._has_txbusy = True def _request(self, url, params=None, timeout=10): """Send a request with parameters.""" @@ -200,9 +201,13 @@ def _get_listinfo_elements(self, entity_type): def wait_device_txbusy(self, ain, retries=10): """Wait for device to finish command execution.""" + if not self._has_txbusy: + return True + for _ in range(retries): if self._has_getdeviceinfos: try: + # getdeviceinfos was added in FritzOS 7.24 plain = self.get_device_infos(ain) dom = ElementTree.fromstring(plain) except exceptions.HTTPError: @@ -213,8 +218,14 @@ def wait_device_txbusy(self, ain, retries=10): dom = self.get_device_element(ain) txbusy = dom.findall("txbusy") + if not txbusy: + # txbusy was added in FritzOS 7.20 + self._has_txbusy = False + return True + if txbusy[0].text == "0": return True + time.sleep(0.2) return False diff --git a/tests/responses/base/device_list_no_txbusy.xml b/tests/responses/base/device_list_no_txbusy.xml new file mode 100644 index 0000000..36d43fb --- /dev/null +++ b/tests/responses/base/device_list_no_txbusy.xml @@ -0,0 +1,25 @@ + + + + 0 + Kitchen + + + + + + + + + + + + 0 + 0 + + 0 + 255 + + + + \ No newline at end of file diff --git a/tests/test_fritzhome.py b/tests/test_fritzhome.py index b7e56f5..9a11167 100644 --- a/tests/test_fritzhome.py +++ b/tests/test_fritzhome.py @@ -345,15 +345,44 @@ def test_wait_tx_busy(self): ] assert self.fritz.wait_device_txbusy("11960 0089208") + assert self.mock.call_count == 2 def test_wait_tx_busy_fallback(self): + """FritzOS <7.24 has no getdeviceinfos""" self.mock.side_effect = [ HTTPError("400 Client Error: Bad Request"), Helper.response("base/device_list_txbusy"), Helper.response("base/device_list_not_txbusy"), ] + # first call will set _has_getdeviceinfos to False + # so sub-sequent calls won't try getdeviceinfos anymore assert self.fritz.wait_device_txbusy("22960 0089208") + assert self.mock.call_count == 3 + + self.mock.reset_mock() + self.mock.side_effect = [ + Helper.response("base/device_list_txbusy"), + Helper.response("base/device_list_not_txbusy"), + ] + + assert self.fritz.wait_device_txbusy("22960 0089208") + assert self.mock.call_count == 2 + + def test_wait_tx_busy_no_txbusy(self): + """FritzOS <7.20 has no txbusy and no getdeviceinfos""" + self.mock.side_effect = [ + HTTPError("400 Client Error: Bad Request"), + Helper.response("base/device_list_no_txbusy"), + ] + + # first call will set _has_txbusy to False, those skip all sub-sequent calls + assert self.fritz.wait_device_txbusy("32960 0089208") + assert self.mock.call_count == 2 + self.mock.reset_mock() + + assert self.fritz.wait_device_txbusy("32960 0089208") + assert self.mock.call_count == 0 def test_wait_tx_busy_failed(self): self.mock.side_effect = [ @@ -362,3 +391,4 @@ def test_wait_tx_busy_failed(self): ] assert not self.fritz.wait_device_txbusy("11960 0089208", 1) + assert self.mock.call_count == 1