TP-Link Tapo Plug P115: Difference between revisions
mNo edit summary |
|||
| Line 19: | Line 19: | ||
Basically: | Basically: | ||
* P100 is big an clunky | * P100 is big an clunky | ||
* P105 supports energy monitoring | * P105 same as P100 but supports energy monitoring | ||
* P110 is the same as P100 but a smaller-sized version | * P110 is the same as P100 but a smaller-sized version | ||
* P115 is both small and supports energy monitoring | * P115 is both small and supports energy monitoring | ||
Latest revision as of 06:53, 16 August 2024
Matter
While the standard of home automation interfaces grows toward "Matter" - there are still many manufacturer-depended protocols in use. Tapo is such a protocol. Lucky for us some people managed to reverse-engineer most of its functions. With this we can take control of these devices and make them do what we want.
Tapo Plug Control
TP-Link has two similar product-lines that are not compatible. It seems that Tapo is a bit newer but both products are said to be supported and updated. This guide is made for the Tapo P115 plug:
Counter part (US outlets):
Basically:
- P100 is big an clunky
- P105 same as P100 but supports energy monitoring
- P110 is the same as P100 but a smaller-sized version
- P115 is both small and supports energy monitoring
The Tapo devices can officially only be controlled with the TP-Link Tapo app, you need to register for an account and link your devices. Ultimately, credentials will be stored on the device, a continuous live internet connection is not necessary after that.
Setup
With the TP-Link Tapo app:
- Connect to your Tapo account
- To restart setup of Wifi: hold the reset button for 5 seconds
- To factory reset the Tapo device: hold the reset button for 10 seconds
- The Tapo device will start with a Wifi open network
- Connect to this network with you mobile device
- Detect and register the device with the app
- Using the app, connect the device to your Wifi Guest network
The device is now in your Wifi network, for the next part it is best to make sure it always receives the same IP address. You can configure this in the DHCP settings in your router.
Firmware updates
- Currently (2023 july) having firmware 1.2.3 Build 230425 Rel. 142542 and it works
- Once you have everything working it is probably best to disable automatic firmware update from the app
Python control
There are some people who managed to work out how to control this device without the app in the local network. It this particular case using a Python module.
I used the code from this project:
pip3 install PyP100
Packages are installed in the 'local' directory of the user: /$HOME/.local/lib/python3.7/site-packages/
Login python3:
import PyP110 p110 = PyP100.P110(ipAddress, user, password) #Creates the cookies required for further methods p110.handshake() #Sends credentials to the plug and creates AES Key and IV for further methods p110.login()
Control python3:
#Turns the connected plug on p110.turnOn() #Turns the connected plug off p110.turnOff() #Toggles the state of the connected plug p110.toggleState() #Turns the connected plug on after 10 seconds p110.turnOnWithDelay(10) #Turns the connected plug off after 10 seconds p110.turnOffWithDelay(10) #Returns dict with all the device info of the connected plug print( p110.getDeviceInfo() ) #The P110 has all the same basic functions as the plugs and additionally allow for energy monitoring. print( p110.getEnergyUsage() )
Reverse Engineering
Some notes
- The device connects to outside servers, using the app you can control it from anywhere.
- If you block internet access to the device:
- You can still control it with the app from within your local network. From outside the network it will look offline.
- Once it has been without power, a function like 'get_energy_usage' will stop working (error -1003) until it has had a connection to the internet. It needs only a minute or so to make it work again.
- Datetime is not synced and starts at 2000-01-01 after boot, but we can set it ourselves
- With internet access it connects to these domains:
- ntp.org, pool.ntp.org (sync datetime)
- security.iot.i.tplinknbu.com, aps1-openapi.i.tplinknbu.com
- n-euw1-device-api.tplinkcloud.com, euw1-device-cloudgateway.iot.i.tplinknbu.com
Project: Tapo-plug
The "tapo-plug" project didn't work out for me but it has some reverse engineering information (without further documentation)
- https://pypi.org/project/tapo-plug/
- firmware Tapo P105, 1.3.2 Build 20210122
- Firmware list on GitHub
Some method examples may help figuring out how other methods should be called:
- get_device_running_info
- { "method": "get_device_running_info" }
- get_device_usage
- { "method": "get_device_usage" }
- set_led_info
- { "method": "set_led_info", "params": { "led_status":False, "led_rule":"never", "night_mode":{ "night_mode_type":"unknown", "sunrise_offset":0, "sunset_offset":0, "start_time":0, "end_time":0 } }, "requestTimeMils":0, "terminalUUID": uuid, }
- get_wireless_scan_info
- { "method": "get_wireless_scan_info", "params": { "start_index":0 } }
- set wifi settings
- { "method": "set_qs_info", "params": { 'account': { 'password': b64encode(deviceInfo['tapoEmail'].encode()).decode("utf-8"), 'username': b64encode(deviceInfo['tapoPassword'].encode()).decode("utf-8") }, 'time': { 'latitude': 90, 'longitude': -135, 'region': deviceInfo['region'], 'time_diff': 60, 'timestamp': 1619885501 }, 'wireless': { 'key_type': deviceInfo['key_type'], 'password': b64encode(deviceInfo['password'].encode()).decode("utf-8"), 'ssid': b64encode(deviceInfo['ssid'].encode()).decode("utf-8") } }, "requestTimeMils":0, "terminalUUID": uuid }
- get_schedule_rules
- { "method": "get_schedule_rules", "params": { "start_index":0 } }
- set_device_time
- { 'method': 'set_device_time', 'params': {'time_diff': 60, 'timestamp': round( now().timestamp() ), 'region': 'Europe/Amsterdam' }, 'requestTimeMils':0 }
- edit_schedule_rule on
- { "method": "edit_schedule_rule", "params": { "id": "S3", "enable": True, "mode": "repeat" } } )
Various possible methods found as text in the firmware
| Category | Method | Type | Params | Error | Result |
|---|---|---|---|---|---|
| Network | get_wireless_scan_info | information | start_index:0 | 0 | |
| Network | set_wireless_info | settings | -1008: Parameter? | ||
| Network | set_qs_info | settings | -1003: Invalid json | ||
| Network | set_qs_extra_info | settings | 0 | ||
| Network | connect_cloud | action | 0 | ok | |
| Network | get_connect_cloud_state | information | 0 | Status=0: not connected | |
| Network | account_sync | action | 0 | ok, what does it do? | |
| Firmware | fw_download | action | does the upgrade: dl and reboot | needs internet access | |
| Firmware | get_fw_download_state | information | shows the download, progress and status: 0=ok, 2=needs upgrade, 3=upgrading | ok | |
| Firmware | get_latest_fw | information | checks for updated firmware | internet access | |
| Log | get_flash_log | information | -1002: Method? | ||
| Log | set_flash_log | settings | -1002: Method? | ||
| Log | get_device_log | information | -1002: Method? | ||
| Log | set_device_log | settings | -1002: Method? | ||
| Log | get_device_running_info | information | 0 | ok | |
| Device | get_device_info | information | 0 | ok | |
| Device | set_device_info | settings | Set Plug on/of, Nickname | ||
| Device | get_led_info | information | 0 | ok | |
| Device | set_led_info | settings | -1601: Cloud? | ||
| Device | get_device_time | information | 0 | Get timestamp, region | |
| Device | set_device_time | settings | 0 | Set timestamp, region | |
| Device | get_device_usage | information | 0 | ok | |
| Device | get_energy_usage | information | 0 | ok, cloud access? | |
| Device | get_diagnose_status | information | -1002: Method? | no | |
| Device | get_factory_info | information | -1002: Method? | ||
| Device | get_ffs_info | information | 0 | ok, pin? | |
| Schedule | get_next_event | information | 0 | ok | |
| Schedule | get_schedule_day_runtime | information | -1002: Method? | ||
| Schedule | get_schedule_month_runtime | information | -1002: Method? | ||
| Schedule | get_schedule_rules | information | start_index:0 | 0 | ok |
| Schedule | set_schedule_all_enable | settings | -1001: Parameter? | ||
| Schedule | add_schedule_rule | settings | -1001: Parameter? | ||
| Schedule | edit_schedule_rule | settings | -1001: Parameter? | ||
| Schedule | remove_schedule_rules | settings | -1008: Parameter? | ||
| Schedule | remove_all_schedule_runtime | settings | -1002: Method? | ||
| Schedule | get_countdown_rules | information | 0 | ok | |
| Schedule | add_countdown_rule | settings | -1008: Parameter? | ok, internet access | |
| Schedule | edit_countdown_rule | settings | -1001: Parameter? | ||
| Schedule | remove_countdown_rules | settings | -1008: Parameter? | ||
| Antitheft | get_antitheft_rules | information | 0 | ok | |
| Antitheft | set_antitheft_all_enable | settings | -1001: Parameter? | ||
| Antitheft | add_antitheft_rule | settings | -1008: Parameter? | ||
| Antitheft | edit_antitheft_rule | settings | -1001: Parameter? | ||
| Antitheft | remove_antitheft_rules | settings | -1008: Parameter? | ||
| Other | heart_beat | -1002: Method? | |||
| Other | exec_atcmd | -1008: Parameter? | |||
| Other | sync_env | 0 | ok, what does it do? | ||
| Other | close_device_ble | -1002: Method? | |||
| Other | close_device_ble | -1002: Method? | |||
| Other | component_nego | 0 | |||
| Other | qs_component_nego | 0 | |||
| Other | device_reboot | action | 0 | ||
| Other | device_reset | action | factory reset? | ||
| Other | get_inherit_info | information | 0 | ||
| Other | set_inherit_info | settings | -1001: Parameter? |
NOTES
Check for upgrades:
{ "method": "get_latest_fw" }
{
"result": {
"type": 2,
"fw_ver": "1.2.3 Build 230425 Rel.142542",
"release_date": "2023-06-07",
"release_note": "Modifications and Bug Fixes:\n1. Optimized performance of Energy Monitoring.\n2. Fixed some minor bugs.",
"fw_size": 786432,
"hw_id": "6F7160E893925CCDAF804C57049E549F",
"oem_id": "763B71FDC7202E1AC59AB1909F97296B",
"need_to_upgrade": true
},
"error_code": 0
}
Do the upgrade:
{ "method": "fw_download" }
Check for progress:
{ "method": "get_fw_download_state" }
{
"result": {
"status": 2,
"download_progress": 71,
"reboot_time": 5,
"upgrade_time": 5,
"auto_upgrade": false
},
"error_code": 0
}
TODO
- Is it possible get the downloadlink of the current Firmware. How does the checksum work? It might be possible to use the firmware functions and find the download link.
- Can we fix the problem when there is no internet access and after a power loss