Dec 172017
 

I was having issues with one of my new tp-link HS110 smart plugs reporting >28,000 watts current power consumption (obviously not correct since that device would light on fire and explode at that point).

In the app, it reported the firmware was v1.1.1 and there were no updates available.

You can check firmware version by clicking on the device in the Kasa app then clicking on the settings icon in the top right. This will show device info including firmware version. My devices are all hardware version 1.0 although I’ve read there may be a 2.0 hw version with different firmware. I checked for updates from the main screen in the Kasa app by clicking the 3 horizontal bar menu in the top left then Settings > Firmware Update. That screen reported no updates.

I contacted tp-link support who said they’d investigate. Shortly thereafter they sent me a link to use their firmware upgrade tool

The upgrade tool is no longer available on their FAQ page like it previously was, but it’s still located at the same location. It appears the device is written in Python and contains a small HTTP server bundled with it to serve up the firmware over the local network.

When I tried to scan from inside the utility, it couldn’t find any of my outlets/plugs.

My network subnet is 172.16.0.0/22 and the devices have static DHCP addresses all set to 172.16.2.0/24. The tool appeared to be sending a UDP broadcast to 255.255.255.255:9999. I couldn’t see this anywhere in Wireshark and these devices appear to listen to TCP 9999 not UDP 9999. I found the UDP broadcast information by watching main.exe with Process Monitor.

I ended up using pyHS100 Python module which is a 3rd party interface to communicate with tp-link smart devices. The official version doesn’t have support for modifying firmware although someone has already added this and has a pending pull request. Someone has already reverse engineered and documented the API including firmware updates

To update the firmware:

  1. Download tp-link’s upgrade tool found here http://static.tp-link.com/iotUpgradeTool_V1.0.zip
    1. Extract the contents and notice there is a firmware folder with firmware for various devices inside. For my HS110 U.S. version, it has a firmware v1.2.3 file
    2. Inside the firmware/ directory there’s an application called hfs.exe–this is a light-weight HTTP server used to serve firmware on your local network
  2. Download the SmartDevice-API-Addition branch from kdschlosser’s fork of pyHS100
    1. You may want to check the official version to see if this code has been merged in/there are any updates
  3. Start a web server to serve the firmware directory. You can use hfs.exe by opening it and selecting Menu > Add folder from disk… and selecting the firmware folder. You could also use Python’s http.server or anything else. Note the URL to the correct firmware file for your device and make sure it can be successfully downloaded with the web server
  4. Start python3 and import the SmartPlug module from pyHS100
  5. Create an instance using your device’s IP
  6. Send the device the firmware URL
  7. Check firmware download status
  8. Flash the device
  9. Wait about 1-2 minutes while the device updates, power cycles, and comes back online
>>> from pyHS100 import SmartPlug
>>> plug = SmartPlug('172.16.2.6')
>>> plug.hw_info
 {'sw_ver': '1.1.1 Build 160725 Rel.164033', 'hw_ver': '1.0', 'mac': '50:C7:BF:xx:xx:xx', 'hwId': '60FF6B258734EA6880E186F8xxxxxxxx', 'fwId': '060BFEA28A8CD1E67146EBxxxxxxx', 'oemId': 'FFF22CFF774A0B89F7624BFxxxxxx', 'dev_name': 'Wi-Fi Smart Plug With Energy Monitoring'}
>>> plug.firmware_download_url('http://172.16.1.1/firmware/hs110v1_us_1.2.3_Build_171016_Rel.100427.bin')
>>> plug.firmware_download_state
 {'ratio': 100, 'flash_time': 66, 'reboot_time': 20}
>>> plug.firmware_download_flash()
>>> plug.hw_info
 {'sw_ver': '1.2.3 Build 171016 Rel.100427', 'hw_ver': '1.0',  ...}