diff --git a/example.py b/example.py index 001d6d2..efe516f 100755 --- a/example.py +++ b/example.py @@ -34,9 +34,9 @@ def ls(client): print('{0.id}: {0.name} ({0.type.name} {0.model_id})'.format(device)) -def mon(client, device_id): - """Monitor any device, displaying generic information about its - status. +def gen_mon(client, device_id): + """Monitor any other device but AC device, + displaying generic information about its status. """ device = client.get_device(device_id) @@ -72,18 +72,11 @@ def mon(client, device_id): pass -def ac_mon(client, device_id): +def ac_mon(ac): """Monitor an AC/HVAC device, showing higher-level information about its status such as its temperature and operation mode. """ - device = client.get_device(device_id) - if device.type != wideq.DeviceType.AC: - print('This is not an AC device.') - return - - ac = wideq.ACDevice(client, device) - try: ac.monitor_start() except wideq.core.NotConnectedError: @@ -106,6 +99,8 @@ def ac_mon(client, device_id): 'on' if state.is_on else 'off' ) ) + else: + print('no state. Wait 1 more second.') except KeyboardInterrupt: pass @@ -113,6 +108,18 @@ def ac_mon(client, device_id): ac.monitor_stop() +def mon(client, device_id): + """Monitor any device, displaying generic information about its + status. + """ + + device_class = client.get_device_obj(device_id) + if isinstance(device_class, wideq.ACDevice): + ac_mon(device_class) + else: + gen_mon(client, device_id) + + class UserError(Exception): """A user-visible command-line error. """ @@ -185,7 +192,6 @@ def ac_config(client, device_id): EXAMPLE_COMMANDS = { 'ls': ls, 'mon': mon, - 'ac-mon': ac_mon, 'set-temp': set_temp, 'set-temp-freezer': set_temp_freezer, 'turn': turn, diff --git a/wideq/ac.py b/wideq/ac.py index 1a08070..54bf93e 100644 --- a/wideq/ac.py +++ b/wideq/ac.py @@ -422,3 +422,6 @@ class ACStatus(object): def is_on(self): op = ACOp(lookup_enum('Operation', self.data, self.ac)) return op != ACOp.OFF + + def __str__(self): + return "ACStatus(%r %r)" % (self.ac, self.data) diff --git a/wideq/client.py b/wideq/client.py index dd6ed6c..2d5b416 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_obj(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 + + device_info = self.get_device(device_id) + if not device_info: + return None + classes = util.device_classes() + if device_info.type in classes: + return classes[device_info.type](self, device_info) + LOGGER.debug('No specific subclass for deviceType %s, using default', + device_info.type) + return Device(self, device_info) + @classmethod def load(cls, state: Dict[str, Any]) -> 'Client': """Load a client from serialized state. diff --git a/wideq/util.py b/wideq/util.py index 67aef76..200ecf0 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, + }