Skip to content

Commit

Permalink
Make sure all device-derived classes accept model kwarg (#1143)
Browse files Browse the repository at this point in the history
* Make sure all device-derived classes accept model kwarg

Converts the missing mapping information on MiotDevice to a warning, fixing #1118

* miotdevice test: check for log entry instead of exception
  • Loading branch information
rytilahti authored Sep 17, 2021
1 parent 1c22607 commit 34bcddd
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 49 deletions.
2 changes: 1 addition & 1 deletion miio/airconditioningcompanionMCN.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def __init__(
) -> None:
if start_id is None:
start_id = random.randint(0, 999) # nosec
super().__init__(ip, token, start_id, debug, lazy_discover)
super().__init__(ip, token, start_id, debug, lazy_discover, model=model)

if model != MODEL_ACPARTNER_MCN02:
_LOGGER.error(
Expand Down
17 changes: 3 additions & 14 deletions miio/airhumidifier_jsq.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,6 @@ def lid_opened(self) -> bool:
class AirHumidifierJsq(Device):
"""Implementation of Xiaomi Zero Fog Humidifier: shuii.humidifier.jsq001."""

def __init__(
self,
ip: str = None,
token: str = None,
start_id: int = 0,
debug: int = 0,
lazy_discover: bool = True,
model: str = MODEL_HUMIDIFIER_JSQ001,
) -> None:
super().__init__(ip, token, start_id, debug, lazy_discover, model=model)
if model not in AVAILABLE_PROPERTIES:
self._model = MODEL_HUMIDIFIER_JSQ001

@command(
default_output=format_output(
"",
Expand Down Expand Up @@ -178,7 +165,9 @@ def status(self) -> AirHumidifierStatus:
# status[7]: water level state (0: ok, 1: add water)
# status[8]: lid state (0: ok, 1: lid is opened)

properties = AVAILABLE_PROPERTIES[self.model]
properties = AVAILABLE_PROPERTIES.get(
self.model, AVAILABLE_PROPERTIES[MODEL_HUMIDIFIER_JSQ001]
)
if len(properties) != len(values):
_LOGGER.error(
"Count (%s) of requested properties (%s) does not match the "
Expand Down
20 changes: 3 additions & 17 deletions miio/chuangmi_plug.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,6 @@ def wifi_led(self) -> Optional[bool]:
class ChuangmiPlug(Device):
"""Main class representing the Chuangmi Plug."""

def __init__(
self,
ip: str = None,
token: str = None,
start_id: int = 0,
debug: int = 0,
lazy_discover: bool = True,
model: str = MODEL_CHUANGMI_PLUG_M1,
) -> None:
super().__init__(ip, token, start_id, debug, lazy_discover)

if model in AVAILABLE_PROPERTIES:
self._model = model
else:
self._model = MODEL_CHUANGMI_PLUG_M1

@command(
default_output=format_output(
"",
Expand All @@ -117,7 +101,9 @@ def __init__(
)
def status(self) -> ChuangmiPlugStatus:
"""Retrieve properties."""
properties = AVAILABLE_PROPERTIES[self.model].copy()
properties = AVAILABLE_PROPERTIES.get(
self.model, AVAILABLE_PROPERTIES[MODEL_CHUANGMI_PLUG_M1]
).copy()
values = self.get_properties(properties)

if self.model == MODEL_CHUANGMI_PLUG_V3:
Expand Down
11 changes: 3 additions & 8 deletions miio/gateway/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ def __init__(
start_id: int = 0,
debug: int = 0,
lazy_discover: bool = True,
*,
model: str = None,
) -> None:
super().__init__(ip, token, start_id, debug, lazy_discover)
super().__init__(ip, token, start_id, debug, lazy_discover, model=model)

self._alarm = Alarm(parent=self)
self._radio = Radio(parent=self)
Expand Down Expand Up @@ -134,13 +136,6 @@ def mac(self):
self._info = self.info()
return self._info.mac_address

@property
def model(self):
"""Return the zigbee model of the gateway."""
if self._info is None:
self._info = self.info()
return self._info.model

@property
def subdevice_model_map(self):
"""Return the subdevice model map."""
Expand Down
4 changes: 1 addition & 3 deletions miio/miot_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ def __init__(
)

if mapping is None and not hasattr(self, "mapping"):
raise DeviceException(
"Neither the class nor the parameter defines the mapping"
)
_LOGGER.warning("Neither the class nor the parameter defines the mapping")

if mapping is not None:
self.mapping = mapping
Expand Down
12 changes: 12 additions & 0 deletions miio/tests/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,15 @@ def test_missing_supported(mocker, caplog):

assert "Found an unsupported model" in caplog.text
assert "for class 'Device'" in caplog.text


@pytest.mark.parametrize("cls", Device.__subclasses__())
def test_device_ctor_model(cls):
"""Make sure that every device subclass ctor accepts model kwarg."""
ignore_classes = ["GatewayDevice", "CustomDevice"]
if cls.__name__ in ignore_classes:
return

dummy_model = "dummy"
dev = cls("127.0.0.1", "68ffffffffffffffffffffffffffffff", model=dummy_model)
assert dev.model == dummy_model
8 changes: 4 additions & 4 deletions miio/tests/test_miotdevice.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from miio import DeviceException, MiotDevice
from miio import MiotDevice
from miio.miot_device import MiotValueType


Expand All @@ -14,11 +14,11 @@ def dev(module_mocker):
return device


def test_missing_mapping():
def test_missing_mapping(caplog):
"""Make sure ctor raises exception if neither class nor parameter defines the
mapping."""
with pytest.raises(DeviceException):
_ = MiotDevice("127.0.0.1", "68ffffffffffffffffffffffffffffff")
_ = MiotDevice("127.0.0.1", "68ffffffffffffffffffffffffffffff")
assert "Neither the class nor the parameter defines the mapping" in caplog.text


def test_ctor_mapping():
Expand Down
10 changes: 8 additions & 2 deletions miio/viomivacuum.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,15 @@ class ViomiVacuum(Device):
retry_count = 10

def __init__(
self, ip: str, token: str = None, start_id: int = 0, debug: int = 0
self,
ip: str,
token: str = None,
start_id: int = 0,
debug: int = 0,
*,
model: str = None,
) -> None:
super().__init__(ip, token, start_id, debug)
super().__init__(ip, token, start_id, debug, model=model)
self.manual_seqnum = -1
self._cache: Dict[str, Any] = {"edge_state": None, "rooms": {}, "maps": {}}

Expand Down

0 comments on commit 34bcddd

Please sign in to comment.