diff --git a/miio/device.py b/miio/device.py index 60a52a55b..855a2d2d8 100644 --- a/miio/device.py +++ b/miio/device.py @@ -16,7 +16,11 @@ ) from .deviceinfo import DeviceInfo from .devicestatus import DeviceStatus -from .exceptions import DeviceInfoUnavailableException, PayloadDecodeException +from .exceptions import ( + DeviceError, + DeviceInfoUnavailableException, + PayloadDecodeException, +) from .miioprotocol import MiIOProtocol _LOGGER = logging.getLogger(__name__) @@ -298,5 +302,17 @@ def sensors(self) -> Dict[str, SensorDescriptor]: sensors = self.status().sensors() return sensors + def supports_miot(self) -> bool: + """Return True if the device supports miot commands. + + This requests a single property (siid=1, piid=1) and returns True on success. + """ + try: + self.send("get_properties", [{"did": "dummy", "siid": 1, "piid": 1}]) + except DeviceError as ex: + _LOGGER.debug("miot query failed, likely non-miot device: %s", repr(ex)) + return False + return True + def __repr__(self): return f"<{self.__class__.__name__ }: {self.ip} (token: {self.token})>" diff --git a/miio/tests/test_device.py b/miio/tests/test_device.py index 82c6beb93..38a6b279d 100644 --- a/miio/tests/test_device.py +++ b/miio/tests/test_device.py @@ -169,3 +169,16 @@ def test_init_signature(cls, mocker): # as some arguments are passed by inheriting classes using kwargs total_args = len(parent_init.call_args.args) + len(parent_init.call_args.kwargs) assert total_args == 8 + + +def test_supports_miot(mocker): + from miio.exceptions import DeviceError + + send = mocker.patch( + "miio.Device.send", side_effect=DeviceError({"code": 1, "message": 1}) + ) + d = Device("127.0.0.1", "68ffffffffffffffffffffffffffffff") + assert d.supports_miot() is False + + send.side_effect = None + assert d.supports_miot() is True