diff --git a/example.py b/example.py index 001d6d2..7d82b5d 100755 --- a/example.py +++ b/example.py @@ -77,13 +77,11 @@ def ac_mon(client, device_id): its status such as its temperature and operation mode. """ - device = client.get_device(device_id) - if device.type != wideq.DeviceType.AC: + ac = client.get_device_class(device_id) + if not isinstance(ac, 'ACDevice'): print('This is not an AC device.') return - ac = wideq.ACDevice(client, device) - try: ac.monitor_start() except wideq.core.NotConnectedError: diff --git a/wideq/ac.py b/wideq/ac.py index 52a4ec8..54bf93e 100644 --- a/wideq/ac.py +++ b/wideq/ac.py @@ -2,7 +2,7 @@ """ import enum -from .client import Device, DeviceInfo, DeviceType +from .client import Device from .util import lookup_enum from .core import FailedRequestError @@ -425,7 +425,3 @@ class ACStatus(object): def __str__(self): return "ACStatus(%r %r)" % (self.ac, self.data) - - -# register device on the global mapping -DeviceInfo.mapping[DeviceType.AC] = ACDevice diff --git a/wideq/client.py b/wideq/client.py index 7134dcc..4587e91 100644 --- a/wideq/client.py +++ b/wideq/client.py @@ -12,6 +12,7 @@ from typing import Any, Dict, Generator, List, Optional from . import core + #: Represents an unknown enum value. _UNKNOWN = 'Unknown' LOGGER = logging.getLogger("wideq.client") @@ -138,6 +139,24 @@ class Client(object): return device return None + def get_device_class(self, device_id): + """Look up a subclass of Device object by device ID. + + Return a Device instance if no subclass exists for the device type. + Return None if the device does not exist. + """ + from . import util + + deviceInfo = self.get_device(device_id) + if deviceInfo == None: + return None + classes = util.device_classes() + if deviceInfo.type in classes: + return classes.get(deviceInfo.type)(self, deviceInfo) + LOGGER.debug('No specific subclass for deviceType %s, using default', deviceInfo.type) + return Device(self, deviceInfo) + + @classmethod def load(cls, state: Dict[str, Any]) -> 'Client': """Load a client from serialized state. @@ -257,16 +276,6 @@ class DeviceInfo(object): This is populated from a JSON dictionary provided by the API. """ - """ - Each subclasse of Device need to be registered here : - DeviceType.AC: ACDevice, - DeviceType.KIMCHI_REFRIGERATOR: RefrigeratorDevice, - DeviceType.DISHWASHER: DishWasherDevice, - DeviceType.DRYER : DryerDevice, - DeviceType.WASHER : WasherDevice, - """ - mapping: Dict[DeviceType, object] = {} - def __init__(self, data: Dict[str, Any]) -> None: self.data = data @@ -297,13 +306,6 @@ class DeviceInfo(object): """ return requests.get(self.model_info_url).json() - def load_object(self): - """Load the registered subclasse Device object according to his type - """ - if self.type in DeviceInfo.mapping: - return DeviceInfo.mapping.get(self.type) - return Device - BitValue = namedtuple('BitValue', ['options']) EnumValue = namedtuple('EnumValue', ['options']) diff --git a/wideq/dishwasher.py b/wideq/dishwasher.py index d5a9ced..f912eff 100644 --- a/wideq/dishwasher.py +++ b/wideq/dishwasher.py @@ -1,7 +1,7 @@ import enum from typing import Optional -from .client import Device, DeviceInfo, DeviceType +from .client import Device from .util import lookup_enum, lookup_reference @@ -158,7 +158,3 @@ class DishWasherStatus(object): def error(self) -> str: """Get the current error.""" return lookup_reference('Error', self.data, self.dishwasher) - - -# register device on the global mapping -DeviceInfo.mapping[DeviceType.DISHWASHER] = DishWasherDevice diff --git a/wideq/dryer.py b/wideq/dryer.py index 304bc03..0b25203 100644 --- a/wideq/dryer.py +++ b/wideq/dryer.py @@ -1,7 +1,7 @@ import enum from typing import Optional -from .client import Device, _UNKNOWN, DeviceInfo, DeviceType +from .client import Device, _UNKNOWN from .util import lookup_enum, lookup_reference @@ -182,7 +182,3 @@ class DryerStatus(object): def error(self) -> str: """Get the current error.""" return lookup_reference('Error', self.data, self.dryer) - - -# register device on the global mapping -DeviceInfo.mapping[DeviceType.DRYER] = DryerDevice diff --git a/wideq/refrigerator.py b/wideq/refrigerator.py index 006495d..7dff39f 100644 --- a/wideq/refrigerator.py +++ b/wideq/refrigerator.py @@ -1,7 +1,7 @@ import enum from typing import Optional -from .client import Device, DeviceInfo, DeviceType +from .client import Device from .util import lookup_enum @@ -138,8 +138,3 @@ class RefrigeratorStatus(object): @property def water_filter_used_month(self): return self.data['WaterFilterUsedMonth'] - - -# register device on the global mapping -DeviceInfo.mapping[DeviceType.KIMCHI_REFRIGERATOR] = RefrigeratorDevice -DeviceInfo.mapping[DeviceType.REFRIGERATOR] = RefrigeratorDevice diff --git a/wideq/util.py b/wideq/util.py index 67aef76..e4c52d8 100644 --- a/wideq/util.py +++ b/wideq/util.py @@ -1,6 +1,6 @@ from typing import TypeVar -from .client import Device +from .client import Device, DeviceType T = TypeVar('T', bound=Device) @@ -29,3 +29,22 @@ def lookup_reference(attr: str, data: dict, device: T) -> str: if value is None: return 'Off' return value + + +def device_classes(): + """The mapping of every Device subclass related to the DeviceType enum + """ + from .ac import ACDevice + from .dryer import DryerDevice + from .dishwasher import DishWasherDevice + from .washer import WasherDevice + from .refrigerator import RefrigeratorDevice + + return { + DeviceType.AC: ACDevice, + DeviceType.KIMCHI_REFRIGERATOR: RefrigeratorDevice, + DeviceType.REFRIGERATOR: RefrigeratorDevice, + DeviceType.DISHWASHER: DishWasherDevice, + DeviceType.DRYER : DryerDevice, + DeviceType.WASHER : WasherDevice, + } diff --git a/wideq/washer.py b/wideq/washer.py index 6756b55..974d3be 100644 --- a/wideq/washer.py +++ b/wideq/washer.py @@ -1,7 +1,7 @@ import enum from typing import Optional -from .client import Device, DeviceInfo, DeviceType +from .client import Device from .util import lookup_enum, lookup_reference @@ -121,7 +121,3 @@ class WasherStatus(object): def error(self) -> str: """Get the current error.""" return lookup_reference('Error', self.data, self.washer) - - -# register device on the global mapping -DeviceInfo.mapping[DeviceType.WASHER] = WasherDevice