fishbigger / TapoP100

A module for controlling the TP-Link Tapo P100 Plugs
MIT License
566 stars 138 forks source link

Controlling the device from outside the local network #96

Open 110nn opened 1 year ago

110nn commented 1 year ago

Hey!

Thanks for the work you've done.

I noticed that the Tapo smartphone app can control the device (P100) even if the smartphone is not on the same Wi-Fi network as the device. Most likely management goes through the tplink server. Have you watched how it works? Can i control the device without being on the same local network?

Thank you!

gablandete commented 1 year ago

Hey I had the same issue.

First you need to create a port forwarding / Port mapping that will open an access from your local network to internet. to do so : 1- Connect to your Router 2- Acces your Advanced settings 3- Create a new port forwarding a) add the IP destination (The IP of your Plug) b) IP Source : check "All" c) Protocole : check "TCP" d) For the three port destinations enter: 80

Then you will need to find you Public IP: https://www.whatismypublicip.com/

Finally, change your credentials in your code : p100 = PyP100.P100("PublicIP:80", "mail@gmail.com","Password")

Tell me if it worked for you.

110nn commented 1 year ago

@gablandete, Hi!

Thanks for the answer!

Yes, i already did that and it works. There is one drawback in such a scheme - sometimes the internal IP of the device changes and the scheme stops working until i reconfigure port forwarding on the router.

But it's still interesting how the Tapo smartphone app works. The application manages the device without first configuring port forwarding. If someone knows how the application works, i will be grateful if you share.

Thanks!

seba1337 commented 1 year ago

This works without any portforwarding, like the phone app, using directly the cloud

import requests from requests import Session

from PyP100 import PyP100

URL = "https://eu-wap.tplinkcloud.com" Payload = { "method": "login", "params": { "appType": "Tapo_Ios", "cloudUserName": "youremailhere", "cloudPassword": "yourpasswordhere", "terminalUUID": "0A950402-7224-46EB-A450-7362CDB903A5" #make sure to randomize a bit these numbers/letters } }

token = requests.post(URL, json=Payload).json()['result']['token'] print(token) URL = "https://eu-wap.tplinkcloud.com?token=" + token Payload = {

#"method": "getDeviceList",
"method":"passthrough", 
"params": {
    "method":"get_device_info", 
    "deviceId": "yourdeviceidhere",
    #"requestData": "{\"method\": \"get_device_info\"}" 
}

}

print(requests.post(URL, json=Payload).json())

110nn commented 1 year ago

@seba1337 Hi!

Thanks for the answer!

But it doesn't work for me :(

First I send an authorization request:

"method": "login", "params": { "appType": "Tapo_Ios", "cloudUserName": "myEmail", "cloudPassword": "myPass", "terminalUUID": "0A950402-7224-46EB-A450-5552CDB902A8" }

I get a token in response:

Array ( [error_code] => 0 [result] => Array ( [accountId] => ******* [regTime] => 2023-01-02 15:19:28 [countryCode] => RU [riskDetected] => 0 [nickname] => MyNickName [email] => myEmail [token] => fa586ab4-BT8St0fxJVISHATeqn4Behy ) )

Next, with the received token, I send a request for a list of devices:

Payload = { "method": "getDeviceList", }

I get a list of my devices, which has deviceId:

Array ( [error_code] => 0 [result] => Array ( [deviceList] => Array ( [0] => Array ( [deviceType] => SMART.TAPOPLUG [role] => 0 [fwVer] => 1.1.1 Build 220921 Rel.141203 [appServerUrl] => https://eu-wap.tplinkcloud.com [deviceRegion] => eu-west-1 [deviceId] => ***************************************** [deviceName] => P100 [deviceHwVer] => 2.0 [alias] => ************************************** [deviceMac] => **************** [oemId] => ***************************************** [deviceModel] => P100(EU) [hwId] => *************************************************** [fwId] => ***************************************** [isSameRegion] => 1 [status] => 0 ) ) ) )

Next, with the received device ID, I send a request for information about the device:

"method": "passthrough", "params": { "method":"get_device_info", "deviceId": "*****************************************", }

But I am getting an error:

Array ( [error_code] => -20571 [msg] => Device is offline )

I thought that the token should be new on every request, but that doesn't work either.

At the same time, my device is online and I can control it through the application on my smartphone.

What am I doing wrong?

Thank you!

carbontracking commented 11 months ago

This is exactly what I am hoping to do, retrieve the data from the P110 via the cloud.

@110nn Did you ever get any further joy on this ?

Thanks /Colm

carbontracking commented 11 months ago

@seba1337 Hello, I have the exact same issue as @110nn above, it says the device is offline.

The reply from getDeviceList which matches with the MAC address of the working P110 is

            }, {
                'deviceType': 'SMART.TAPOPLUG', 
                'role': 0, 
                'fwVer': '1.0.7 Build 210629 Rel.174901', 
                'appServerUrl': 'https://eu-wap.tplinkcloud.com', 
                'deviceRegion': 'eu-west-1', 
                'deviceId': '802288EF0EF4C558361594CC36DDB5151EDD9B1E', 
                'deviceName': 'P110', 
                'deviceHwVer': '1.0', 
                'alias': 'Y2hlZXNlIHByZXNzIGZyaWRnZXM=', 
                'deviceMac': '1027F5E061D7', 
                'oemId': 'AE7B616A7168B34151ABBCF86C88DF34', 
                'deviceModel': 'P110(UK)', 
                'hwId': '56DD079101D61D400A11C4A3D41C51DA', 
                'fwId': '00000000000000000000000000000000', 
                'isSameRegion': True, 
                'status': 0
            }

However , when I do

URL = "https://eu-wap.tplinkcloud.com?token=" + token
Payload = {
    "method":"passthrough", 
    "params": {
        "method":"get_device_info", 
        "deviceId": "802288EF0EF4C558361594CC36DDB5151EDD9B1E",
        #"requestData": "{\"method\": \"get_device_info\"}" 
    }
}

print(requests.post(URL, json=Payload).json())

I get the message

-20571 [msg] => Device is offline )

carbontracking commented 11 months ago

@seba1337 @110nn

The more I think about this, the more I think the answer from @seba1337 is spurious, i.e. it proves that one can connect to the cloud-server but gives no indication of how to retrieve Energy usage for a specific device.

Perhaps it is simply impossible...

timothy-holmes commented 11 months ago

You may find this library helpful: https://github.com/piekstra/tplink-cloud-api