Closed israndy closed 2 years ago
Hi @israndy ,
Thanks for giving my library a try. I believe this issue is specific to Python 3.10 on MacOS. It should work fine using version 3.9
I will investigate this tomorrow if I have time to look for any changes I can make to support 3.10 out of the box.
This seems to be related
I checked and there was a .4 update to python, I installed it and noticed in the python folder a command file to install certificates. I did it and ran the script again, and this time it ran cleanly.
The Example.py file appears to show that much of the API is not finished being cut over to asyncio, but at least the top of it runs cleanly.
Of course it worked until I installed MacOS 12.3.1 this morning. I even reinstalled Python and re-ran the certificate command and it's still not working... Odd.
Deleted my python 3.10 and reinstalled python 3.9, like you suggested, thx
OK, under Python 3.9 I am able to get every call in your library working with my Kasa collection. Next trick is making an app with this capability. I started working on it, but whenever I try to collect the realtime and day and month Emeter readings I get diagnostic text from your library (emeter_device.py):
if realtime_data is not None and realtime_data.get('err_code') == 0:
print(f"Found: {realtime_data}")
return CurrentPower(realtime_data)
Is this for a reason? I cannot figure a good way around it w/o making my own copy of your library, but I wanna support your lib and bring you more users.
Should I post this as a separate issue?
@israndy funny you found that! I had opened a PR to address it but apparently never merged it. I'll make that update now.
Version 4.1.2 of the library is now published and removes the print statement - it was vestigial code from debugging.
As for making an app, FWIW, I had started up some work on a React app to expose certain functionality:
https://github.com/piekstra/tplink-kasa-ui
It made use of a simple Python backend API that simply leveraged this library:
https://github.com/piekstra/tplinkcloud-service
The code on both sides hasn't been touched in awhile, so probably isn't in a runnable state. I need to update the service side at some point and then start adding more features to the frontend.
Part of my vision included being able to see your list of devices in the UI, manage their power state, then click into them to edit schedules and view historical and live power data. Haven't had capacity to work on the project for awhile though, sadly.
Thanks for the quick response, downloading the update right now. I'll check out what you have as far as an API goes, but I am really just trying to tie my solar generation to when it's OK for certain devices to run. I should have enough with just the TPLink API you made.
Oh, man, I am sorry, I wasn't clear I guess. It's not just the print() statement in the realtime line, I wrote "whenever I try to collect the realtime and day and month Emeter readings I get diagnostic text", so if you are back in your code anytime, it would be great to get the other two updated as well. Thanks so much, I have learned a LOT about Python reading your code, and finally got comfortable with writing async code, that was always a mystery to me before.
Today I learned about the Pip3 --upgrade option, all very new to me
Oh, man, I am sorry, I wasn't clear I guess. It's not just the print() statement in the realtime line, I wrote "whenever I try to collect the realtime and day and month Emeter readings I get diagnostic text", so if you are back in your code anytime, it would be great to get the other two updated as well. Thanks so much, I have learned a LOT about Python reading your code, and finally got comfortable with writing async code, that was always a mystery to me before.
Today I learned about the Pip3 --upgrade option, all very new to me
🤦
remaining print statements should be addressed in here https://github.com/piekstra/tplink-cloud-api/pull/64
Example code issues
In your readme you include the snippet:
for device in devices:
async def get_info(device):
print(f'Found {device.model_type.name} device: {device.get_alias()}')
print("SYS INFO")
print(json.dumps(device.device_info, indent=2, default=lambda x: vars(x)
if hasattr(x, "__dict__") else x.name if hasattr(x, "name") else None))
print(json.dumps(await device.get_sys_info(), indent=2, default=lambda x: vars(x)
if hasattr(x, "__dict__") else x.name if hasattr(x, "name") else None))
fetch_tasks.append(get_info(device))
await asyncio.gather(*fetch_tasks)
This is very efficient code as it allows the individual TPLink units to get back to the main app whenever they can and the entire code block isn't waiting for individual TPLinks to complete communication.
HOWEVER, since this code prints when it has information to print you end up with a lot of intermingled output from the various TPLink units.
My workaround so that all the info for each unit was printed directly under it's name was to create a list of strings, for each device I would collect the data and save it to a string and then append the entire string to the list. I could then parse the list to display the name and info collected for all the devices. I am a new programmer and don't have ANY cool coding under my belt, I am SURE there is a better solution, just wanted to point out the foible in your example code so you could take another crack at it.
if you want
I realized it's easy to fix:
y = device.device_info
z = await device.get_sys_info()
print(f'Found {device.model_type.name} device: {device.get_alias()}')
print(json.dumps(y, indent=2, default=lambda x: vars(x)
if hasattr(x, "__dict__") else x.name if hasattr(x, "name") else None))
print("SYS INFO")
print(json.dumps(z, indent=2, default=lambda x: vars(x)
if hasattr(x, "__dict__") else x.name if hasattr(x, "name") else None))
This keeps all the info for one device together and not interspersed with other device's information as there is no 'await' allowing another function to run
Also added
z = False
if device.model_type.name != 'HS300CHILD' :
if device.device_info.status :
z = await device.get_sys_info()
instead of the second line above, it removes bad info returns for inactive devices or individual outlets on energy monitoring power strips
I'm going to close this issue for now. Please open up a pull request with the desired changes to the README for review.
I have tried all day to get any part of this API working, perhaps you are in the progress of making a change, but nothing I have done got results. I am sure I am an idiot, but would love to know what I am doing wrong.
I started by downloading the repo from here, I then tried to get the Example.py to run. I was able to get as far as the creation of the device_manager. With Verbose set to True I do see that it has connected to my account and sees all my TPLink devices. Any other command I issue after that fails.
I then tried to change everything out and used the pip3 install command to copy your module to my Mac running MacOS 12.3 and Python 3.10.3. I then copied the code from your ReadMe under "For more advanced usage, you can gather tasks so they all run at once such as in the following example which can fetch a large number of devices' system info very quickly:", above the section "Retrieve devices" into a new python document in a new folder.
Adding my Username and Password I get the following error messages when I run the script, they look to be the same complaint I got all day, don't know what it means: