TP-Link Tapo Plug P115

From WickyWiki


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:

  1. Connect to your Tapo account
  2. To restart setup of Wifi: hold the reset button for 5 seconds
  3. To factory reset the Tapo device: hold the reset button for 10 seconds
  4. The Tapo device will start with a Wifi open network
  5. Connect to this network with you mobile device
  6. Detect and register the device with the app
  7. 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)


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