mihai-dinculescu / tapo

Unofficial Tapo API Client. Works with TP-Link Tapo smart devices. Tested with light bulbs (L510, L520, L530, L610, L630), light strips (L900, L920, L930), plugs (P100, P105, P110, P115, P300), hubs (H100), switches (S200B) and sensors (KE100, T100, T110, T300, T310, T315).
MIT License
318 stars 30 forks source link

missing field `re_power_type #159

Closed zaraquer closed 5 months ago

zaraquer commented 5 months ago

Hi!

I recieved this error booth on rust and python examples on L510 bulbs. Error: Serde(Error("missing field re_power_type", line: 1, column: 550)) I want to use the client to monitor the power usage of the bulbs. What can I do to fix this issue?

mihai-dinculescu commented 5 months ago

It looks like this is a regression of the change in https://github.com/mihai-dinculescu/tapo/issues/135. Can you please call get_device_info_json instead of get_device_info, and paste the output here?

zaraquer commented 5 months ago

After I changed get_device_info to get_device_info_json it works great.:

2024-01-19T09:11:54.974Z INFO tapo_l510 > Device usage: DeviceUsageEnergyMonitoringResult { time_usage: UsageByPeriodResult { today: 28, past7: 1211, past30: 13237 }, power_usage: UsageByPeriodResult { today: 1, past7: 172, past30: 1829 }, saved_power: UsageByPeriodResult { today: 27, past7: 1039, past30: 11408 } }

Thanks for the help and your great work mate!

mihai-dinculescu commented 5 months ago

Sorry, the output that's pasted above is for device usage. Can you please provide the one for device info?

zaraquer commented 5 months ago

Sure, I just changed the sensitive parts.

Device info: Object {"avatar": String("bulb"), "brightness": Number(30), "default_states": Object {"brightness": Object {"type": String("last_states"), "value": Number(30)}}, "device_id": String("8023C0D888DD972F67F68BF0809ABE791EF4B5E0"), "device_on": Bool(false), "fw_id": String("7BECA9DC454565672FEC87D1104F9972"), "fw_ver": String("1.3.0 Build 20230831 Rel. 75926"), "has_set_location_info": Bool(true), "hw_id": String("93F94D88DA9499F43B929DD38EBDF09A"), "hw_ver": String("1.0.0"), "ip": String("xx.xx.xx.xx"), "lang": String("hu_HU"), "latitude": Number(21412431), "longitude": Number(212141), "mac": String("11-11-11-11-11-11"), "model": String("L510 Series"), "nickname": String("S29ueWhh"), "oem_id": String("6B97E8E19CE8019B59D9E81CEDD371BD"), "on_time": Number(0), "overheated": Bool(false), "region": String("Europe/Budapest"), "rssi": Number(-46), "signal_level": Number(3), "specs": String("EU"), "ssid": String("V29yay1OZXR3b3Jr"), "time_diff": Number(60), "type": String("SMART.TAPOBULB")}

Not fully okay as I see it now, because it wont get forexample the nickname correctly.

mihai-dinculescu commented 5 months ago

Thank you, this is very helpful.

The get_device_info_json function gives the response as it comes from the Tapo API without trying to parse it in any way. Decoding the nickname is part of the parsing that get_device_info does.

I know what needs changing now. re_power_type seems optional.

mihai-dinculescu commented 5 months ago

The fix has been released in Tapo Rust v0.7.8 and Tapo Python v0.1.5.

mihai-dinculescu commented 5 months ago

@zaraquer, it would be lovely if you could try out the new version. I suspect that there might be some further errors :(

zaraquer commented 5 months ago

Thanks! I will check it today a bit later. Sorry for the late answer, I was away from my computer. BTW thanks again for your fast and amazing work!

zaraquer commented 5 months ago

I tried the python version first. With get_device_info:

Traceback (most recent call last): File "/root/tapo/tapo-py/examples/tapo_l510.py", line 40, in asyncio.run(main()) File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run return loop.run_until_complete(main) File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete return future.result() File "/root/tapo/tapo-py/examples/tapo_l510.py", line 32, in main device_info = await device.get_device_info() Exception: Serde(Error("missing field re_power_type", line: 1, column: 539))

After I changed it to get_device_info_json:

Traceback (most recent call last): File "/root/tapo/tapo-py/examples/tapo_l510.py", line 40, in asyncio.run(main()) File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run return loop.run_until_complete(main) File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete return future.result() File "/root/tapo/tapo-py/examples/tapo_l510.py", line 33, in main print(f"Device info: {device_info.to_dict()}") AttributeError: 'dict' object has no attribute 'to_dict'

mihai-dinculescu commented 5 months ago

Are you sure you're using the latest version? I'm surprised to see the missing field re_power_type error occurring.

to_dict is required only on the result of get_device_info. get_device_info_json returns a dict straight up, so you should not call to_dict on its result.

zaraquer commented 5 months ago

Yeah, its the latest.

git log

commit 49238242e2baf9f79482ff6cd1ad3b2dc7beb8da (HEAD -> main, origin/main, origin/HEAD) Author: Dinculescu mihai.dinculescu@outlook.com Date: Sun Jan 21 21:23:35 2024 +0000

tapo-py: Add support for the L530, L630, and L900 devices

Addresses #123.

commit e9d2953afd79144e15b90ad70dd2abaf7573ec77 (tag: py-v0.1.5) Author: Dinculescu mihai.dinculescu@outlook.com Date: Sat Jan 20 21:28:49 2024 +0000

tapo-py: Release v0.1.5

commit c8307d5e15d929cffda29f694a2a38a0b28e32da (tag: v0.7.8) Author: Dinculescu mihai.dinculescu@outlook.com Date: Sat Jan 20 21:27:13 2024 +0000

Release v0.7.8

I'm testing with the example's.

zaraquer commented 5 months ago

Okay, I deleted dict, now this is what I get:

python examples/tapo_l510.py Turning device on... Waiting 2 seconds... Setting the brightness to 30%... Waiting 2 seconds... Turning device off... Device info: {'avatar': 'bulb', 'brightness': 30, 'default_states': {'brightness': {'type': 'last_states', 'value': 30}}, 'device_id': '8023C0D888DD972F67F68BF0809ABE791EF4B5E0', 'device_on': False, 'fw_id': '7BECA9DC454565672FEC87D1104F9972', 'fw_ver': '1.3.0 Build 20230831 Rel. 75926', 'has_set_location_info': True, 'hw_id': '93F94D88DA9499F43B929DD38EBDF09A', 'hw_ver': '1.0.0', 'ip': 'xx.xx.xx.xx', 'lang': 'hu_HU', 'latitude': 554786, 'longitude': 332565, 'mac': 'aa-aa-aa-aa-aa-aa', 'model': 'L510 Series', 'nickname': 'S29ueWhh', 'oem_id': '6B97E8E19CE8019B59D9E81CEDD371BD', 'on_time': 0, 'overheated': False, 'region': 'Europe/Budapest', 'rssi': -46, 'signal_level': 3, 'specs': 'EU', 'ssid': 'V29yay1OZXR4b3Jr', 'time_diff': 60, 'type': 'SMART.TAPOBULB'} Device usage: <builtins.DeviceUsageEnergyMonitoringResult object at 0x7f1f75495590>

mihai-dinculescu commented 5 months ago

Hmm, before running the example, can you please run

cd tapo-py
poetry install
poetry shell
maturin develop

and try get_device_info again?

zaraquer commented 5 months ago

I did what you suggest:

(tapo-Q5KVV4uC-py3.10)~/tapo/tapo-py# python examples/tapo_l510.py
Turning device on...
Waiting 2 seconds...
Setting the brightness to 30%...
Waiting 2 seconds...
Turning device off...
Traceback (most recent call last):
  File "/root/tapo/tapo-py/examples/tapo_l510.py", line 40, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/root/tapo/tapo-py/examples/tapo_l510.py", line 32, in main
    device_info = await device.get_device_info()
Exception: Serde(Error("missing field `dynamic_light_effect_enable`", line: 1, column: 722))
mihai-dinculescu commented 5 months ago

That's brilliant, thank you. This error does make sense, and it's what I was afraid of. I'll have a fix in the next couple of days.

mihai-dinculescu commented 5 months ago

The fix has been released in Tapo Rust v.0.7.9 and Tapo Python v0.2.0.