jonghwanhyeon / python-switchbot

A Python library to control SwitchBot devices connected to SwitchBot Hub

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Virtual IR devices are not handled

markszabo opened this issue · comments

SwitchBot Hubs can send IR commands to home appliances, and one can add these home appliances as virtual devices in the app (ref). The API response is significantly different for these devices (sometimes called remotes in the API), e.g. they don't have MAC addresses, which currently breaks this library, e.g.:

>>> switchbot.devices()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/site-packages/switchbot/__init__.py", line 521, in devices
    devices.append(self.device(id))
  File "/usr/local/lib/python3.9/site-packages/switchbot/__init__.py", line 513, in device
    return Device.factory(self, id)
  File "/usr/local/lib/python3.9/site-packages/switchbot/__init__.py", line 85, in factory
    device, _ = Device._query_device(switchbot, sanitize_id(id))
  File "/usr/local/lib/python3.9/site-packages/switchbot/__init__.py", line 80, in _query_device
    raise KeyError
KeyError

The reason is that the switchbot._api("get", "get_devices") call in https://github.com/jonghwanhyeon/python-switchbot/blob/main/switchbot/__init__.py#L74 returns something similar (I have onne SwitchBot bot, one Hub Mini and one AC added:

{   'deviceList': [   {   'ble_version': 17,
                          'cloudServiceAble': False,
                          'device_detail': {   'device_type': 'WoLinkMini',
                                               'ip': '192.168.2.1',
                                               'isEncrypted': False,
                                               'model': '0',
                                               'parent_device': '00:00:00:00:00:00',
                                               'pubtopic': 'switchlink/123456789ABCDEF0/app_to_link',
                                               'remote': 'on',
                                               'subtopic': 'switchlink/123456789ABCDEF0/link_to_app',
                                               'support_cmd': [],
                                               'update_time': '1610279471',
                                               'version': '1.0.0',
                                               'wifi_mac': '123456789ABC'},
                          'device_mac': '123456789ABC',
                          'device_name': 'Switch Bot Hub',
                          'hardware_version': 4,
                          'isLinkage': True,
                          'json_version': 1,
                          'netConfigAble': False,
                          'platforms': [],
                          'userID': '12345678-1234-1234-1234-123456789ABC',
                          'user_name': 'user@example.com',
                          'wifi_version': 19},
                      {   'ble_version': 0,
                          'cloudServiceAble': True,
                          'device_detail': {   'device_type': 'WoHand',
                                               'ip': '192.168.2.1',
                                               'isEncrypted': False,
                                               'model': '0',
                                               'parent_device': '12:34:56:78:9A:BC',
                                               'pubtopic': 'switchlink/123456789ABCDEF0/app_to_link',
                                               'remote': 'on',
                                               'subtopic': 'switchlink/123456789ABCDEF0/link_to_app',
                                               'support_cmd': [   {   'key': 'press',
                                                                      'value': 'ACTH '
                                                                               'SY '
                                                                               '123456789ABCDEF0'}],
                                               'update_time': '1610280920',
                                               'version': '1.0.0',
                                               'wifi_mac': 'FFFFFFFFFFFF'},
                          'device_mac': '123456789ABC',
                          'device_name': 'My Switch',
                          'hardware_version': 0,
                          'isLinkage': True,
                          'json_version': 1,
                          'netConfigAble': False,
                          'platforms': ['IFTTT', 'GoogleHome', 'Alexa'],
                          'userID': '12345678-1234-1234-1234-123456789ABC',
                          'user_name': 'user@example.com',
                          'wifi_version': 0}],
    'remoteList': [   {   'acType': '1',
                          'brandEn': 'Toshiba AC',
                          'code': 'H4sIAAAAAAAAALVdO5IcxxGFs32DvQcMnY<...>IWna6IIfCFvz5Clb+DsHfWj9rUfwCsxqSGj3MAAA==',
                          'codeType': '3',
                          'createTime': '202101102102',
                          'dbVersion': 20,
                          'hxdIndex': '160672467',
                          'keyDetail': [],
                          'keyMap': 'off:0:134;16,cool,autowin,on:134:192;1<...>,1,on:29009:191;-100,wind,2,on:29200:192;-100,wind,3,on:29392:191',
                          'parentHubMac': '123456789ABC',
                          'priority': '1161600',
                          'remoteID': '01-202101102100-12345678',
                          'remoteName': 'Air Conditioner',
                          'serial': 12345,
                          'sn': '123456789ABCDEF0',
                          'type': 1,
                          'userID': '12345678-1234-1234-1234-123456789ABC',
                          'user_name': 'user@example.com',
                          'zipCodeVersion': 12}],
    'sceneList': [],
    'userInfo': {   'openApiToken': {   'exp': 0,
                                        'iat': 0,
                                        'token': '',
                                        'version': 1},
                    'sortInfo': {   'array': [   '12:34:56:78:9A:BC',
                                                 '01-202101102100-12345678',
                                                 '123456789ABC'],
                                    'timeStamp': 1610280440600},
                    'targetVersion': {   'WoLinkMiniBleVersion': 17,
                                         'WoLinkMiniWifiVersion': 19},
                    'temperatureUnitC': True,
                    'userName': 'user@email.com'}}

and when _query_device(cls, switchbot, id) is called with the id 01-202101102100-12345678 it is not found (as it's not in deviceList but in remoteList and also not device_mac rather remoteID). So extending _query_device(cls, switchbot, id) to something like this would solve this:

@classmethod
def _query_device(cls, switchbot, id):
    data, updated = switchbot._api("get", "get_devices")

    for device in data["deviceList"]:
        if device["device_mac"] == id:
            return device, updated

    for remote in data["remoteList"]:
        if remote["remoteID"] == id:
            return remote, updated

    raise KeyError

However the problem is that the properties are so different for a remote than an actual device, that this just makes the code break in https://github.com/jonghwanhyeon/python-switchbot/blob/main/switchbot/__init__.py#L87 I think the solution would be to create a new type for remote devices, but the official doc (see #7) has a different API response so I think this should only happen after the move to the other API.

This is something I might end up implementing, but wanted to get your opinion on it first.

@markszabo I also needed this for myself, so I created a PR. I'm not sure what the issue you had back then, but it works for me to turn on/off fans and my "Other" remotes.

#12

Close this issue thanks to PR #12 by @ekawatani