piekstra / tplink-cloud-api

A Python library to remotely control TP-Link smart home devices using their cloud service - no need to be on the same network as your devices
GNU General Public License v3.0
41 stars 11 forks source link

Add Support for Archer A8(EU) Router device #65

Open Gipssik opened 2 years ago

Gipssik commented 2 years ago

I get TypeError every time I use some functions that are coroutines.

Configuration:

Code:

import asyncio
import os

from dotenv import load_dotenv
from tplinkcloud import TPLinkDeviceManager
from tplinkcloud.device import TPLinkDevice

load_dotenv()
username = os.getenv("USERNAME")
password = os.getenv("PASSWORD")
device_manager = TPLinkDeviceManager(username, password)

async def main():
    device: TPLinkDevice = await device_manager.find_device("Archer A8")
    print(await device.toggle())

if __name__ == "__main__":
    asyncio.run(main())

Traceback:

Traceback (most recent call last):
  File "/path/to/project/router/main.py", line 20, in <module>
    asyncio.run(main())
  File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/path/to/project/router/main.py", line 16, in main
    print(await device.toggle())
  File "/path/to/project/router/venv/lib/python3.10/site-packages/tplinkcloud/device.py", line 83, in toggle
    if await self.is_on():
  File "/path/to/project/router/venv/lib/python3.10/site-packages/tplinkcloud/device.py", line 97, in is_on
    device_sys_info = await self.get_sys_info()
  File "/path/to/project/router/venv/lib/python3.10/site-packages/tplinkcloud/device.py", line 94, in get_sys_info
    return await self._get_sys_info()
  File "/path/to/project/router/venv/lib/python3.10/site-packages/tplinkcloud/device.py", line 89, in _get_sys_info
    return await self._pass_through_request('system', 'get_sysinfo', None)
  File "/path/to/project/router/venv/lib/python3.10/site-packages/tplinkcloud/device.py", line 62, in _pass_through_request
    response = await self._client.pass_through_request(
  File "/path/to/project/router/venv/lib/python3.10/site-packages/tplinkcloud/device_client.py", line 65, in pass_through_request
    return json.loads(response.result.get('responseData'))
  File "/usr/local/lib/python3.10/json/__init__.py", line 339, in loads
    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict

Process finished with exit code 1

UPD

I started to debug it and found some strange places and the cause of exception I guess.

request_data at line 53, file device.py looks strange:

image

And the cause of exception at line 36, file device_client.py:

image

piekstra commented 2 years ago

@Gipssik what model of device are you trying to find? I wonder if this is an issue with compatibility of the library.

Gipssik commented 2 years ago

@piekstra I'm trying to find my router Archer A8(EU), it's connected to my Tether app. The library finds it and I can get its device_info

piekstra commented 2 years ago

@piekstra I'm trying to find my router Archer A8(EU), it's connected to my Tether app. The library finds it and I can get its device_info

Ahhh that explains it. While this library works with the TP-Link API, it's currently only written to support certain TP-Link Kasa devices. At this time, any other devices are unlikely to be properly accessed via this library. To add support for your device would be a matter of reverse engineering the Tether app or monitoring its network requests and figuring out the API contracts since they are not officially documented.