IoT – IT Nerd Space http://itnerd.space Blog about Cloud, Automation, Android, Smart things... Thu, 27 Jul 2017 22:59:31 +0000 en-US hourly 1 https://wordpress.org/?v=4.7.5 https://i2.wp.com/itnerd.space/wp-content/uploads/2016/10/cropped-99789e30b0a6eac11f33246750ca29f9.jpg?fit=32%2C32 IoT – IT Nerd Space http://itnerd.space 32 32 133306427 How to authenticate to TP Link cloud API with Tasker http://itnerd.space/2017/06/19/how-to-authenticate-to-tp-link-cloud-api-with-tasker/ http://itnerd.space/2017/06/19/how-to-authenticate-to-tp-link-cloud-api-with-tasker/#respond Mon, 19 Jun 2017 23:03:06 +0000 http://itnerd.space/?p=356 We’ve seen in a previous post what is the protocol to authenticate to TP Link cloud API. Now, what about doing that from Tasker you can ask me? Well, that’s very simple actually!

To implement that in Tasker I have used RESTask for Tasker (because I had troubles having the native HTTP Post action work for me):

RESTask for Tasker (Free, Google Play) →

Next create 3 global variables in Tasker (self-explanatory I guess):

  • TPLUSER
  • TPLPASS
  • TPLTERM (use the UUIDv4 you got above)

Then create a new Task with the following 4 actions:

The first action will be a Variable Set %payload:

Name:%payload
To: { "method" :"login",
"params" : {
  "appType" :"Kasa_Android",
  "cloudPassword" :"%TPLPASS",
  "cloudUserName" :"%TPLUSER",
  "terminalUUID" :"%TPLTERM" } }

The second action will be the RESTask call:

Further down we need to set the custom body to %payload:

Then we set the Headers:

The third action will be a Javascriptlet with the following code, to extract the token (from the rtres, passed from  RESTask) to the %mtoken variable:

var mtoken = JSON.parse(rtres).result.token;

Finally, here the fourth action will just be a Flash action, that will show the token:

Flash [ Text:%mtoken Long:On ]

The whole task should end up looking like this:

You can run the Task and it should flash the token on the screen!! Yay

]]>
http://itnerd.space/2017/06/19/how-to-authenticate-to-tp-link-cloud-api-with-tasker/feed/ 0 356
How to authenticate to TP-Link cloud API http://itnerd.space/2017/06/19/how-to-authenticate-to-tp-link-cloud-api/ http://itnerd.space/2017/06/19/how-to-authenticate-to-tp-link-cloud-api/#comments Mon, 19 Jun 2017 23:01:45 +0000 http://itnerd.space/?p=345 This is breaking news! No need to hack into your phone’s backups any more to obtain the TP-Link token!

First you need to generate an UUID v4. You can open https://www.uuidgenerator.net/version4 and pick the one they give you there (no need to create one every time, one is fine, just keep it). This will represent your Client Term ID (like the one of your Kasa App).

Now this is how you can authenticate to the TP Link cloud backend and obtain a token:

We have to do a POST request to https://wap.tplinkcloud.com, with the following payload:

{
 "method": "login",
 "params": {
 "appType": "Kasa_Android",
 "cloudUserName": "XXXXX",
 "cloudPassword": "XXXXX",
 "terminalUUID": "MY_UUID_v4"
 }
}

In the payload, replace cloudUserName and cloudPassword with your TP-Link (or Kasa) credentials, and the terminalUUID with the one you got above.

Remember to pass the Header Content-Type: application/json as well.

No need to have any extra tool, you can simply try it with Hurl.it from your browser:

What you’ll get should look like this:

{
 "error_code": 0,
 "result": {
 "regTime": "2017-01-06 08:42:35",
 "email": "XXXXX",
 "token": "YOUR_TOKEN_HERE"
 }
}

Isn’t that cool? Of course you can implement that in any language, Shell script with cURL, Python, Node.js,… Your token is response.result.token.

In a next post I’ll show how to do the same with Tasker! 😀

From here you can also have a look at this post: Get the end point URL and HS100 Device ID.

]]>
http://itnerd.space/2017/06/19/how-to-authenticate-to-tp-link-cloud-api/feed/ 19 345
How to get the TP-Link HS100 cloud end-point URL? http://itnerd.space/2017/05/21/how-to-get-the-tp-link-hs100-cloud-end-point-url/ http://itnerd.space/2017/05/21/how-to-get-the-tp-link-hs100-cloud-end-point-url/#comments Sun, 21 May 2017 22:50:44 +0000 http://itnerd.space/?p=323 If you have followed my series on how to control the TP-Link HS100 smart plug by communicating with TP-Link Cloud services, you might have seen that there are some common issues related to the URL one need to point the requests to.

I’ve found out a way to know what is the URL, no more hit and miss needed any more!

The only thing that you’ll need is your TP-Link token (see how to get it). In a terminal, run the following command:

curl -s --request POST "https://wap.tplinkcloud.com?token=YOUR_TOKEN_HERE HTTP/1.1" \
 --data '{"method":"getDeviceList"}' \
 --header "Content-Type: application/json"

As an alternative, you can use hurl.it, an online version of curl, like shown on the picture below:

As Parameters use simply this:

{"method":"getDeviceList"}

As the name of the method implies, this will list all your HS100 devices (maybe other, please tell me what you see!). You should get something like this:

{
 "result" : {
 "deviceList" : [
 {
 "appServerUrl" : "https://eu-wap.tplinkcloud.com",
 "isSameRegion" : true,
 "deviceMac" : "",
 "status" : 1,
 "hwId" : "XXXX....",
 "deviceId" : "XXXX....",
 "oemId" : "XXXX....",
 "fwVer" : "1.0.8 Build 151101 Rel.24452",
 "deviceType" : "IOT.SMARTPLUGSWITCH",
 "alias" : "My Smart Plug",
 "fwId" : "BFF24826FBC561803E49379DBE74FD71",
 "deviceName" : "Wi-Fi Smart Plug",
 "deviceHwVer" : "1.0",
 "role" : 0,
 "deviceModel" : "HS100(EU)"
 }
 ]
 },
 "error_code" : 0
}

In the results above, we’ll get a list of all our TPLink devices, with their alias (the custom name we have given it), the deviceId, and the appServerUrl.

The appServerUrl is the one we’ll need to use in further POST requests, to control the plug.

]]>
http://itnerd.space/2017/05/21/how-to-get-the-tp-link-hs100-cloud-end-point-url/feed/ 12 323
Control your TP-Link HS100 smart plug from your Android Watch! http://itnerd.space/2017/04/03/control-your-tp-link-hs100-smart-plug-from-your-android-watch/ http://itnerd.space/2017/04/03/control-your-tp-link-hs100-smart-plug-from-your-android-watch/#respond Mon, 03 Apr 2017 22:11:01 +0000 http://itnerd.space/?p=254 In this post I’ll show how I control my TP-Link HS100 smart plug right from my LG G Watch R Android smart watch, from anywhere, which is very handy.

The first thing we need is the ability to control the HS100 smart plug from Tasker on our Android phone. If you haven’t already, be sure to check my preview post where I explain how to create two Tasker Tasks, that will turn our plug On and Off.

For the next step I’ll use the WearTasker: with this app you can choose some of your Tasker tasks and publish them on your watch. They will show as buttons when you open WearTasker on your wrist, and the corresponding task will run when pressed. Quite simple. TBH WearTasker  feels like a natural extension of Tasker to Android Wear.

WearTasker - Tasker for Wear (Free+, Google Play) →

You can buy a Pro in-app purchase if you’d like, which unlocks some cool features, but what I use here works with the free version.

So let’s publish both our smart plug tasks. Open Wear Tasker on your phone, and create a new shortcut. Choose your “Power On Plug” task, and name it however you like. You can also select an icon and a color. Then repeat the same operations with the other task:

 

Back to the app, it should now look like this:

And that’s how it will look on your watch:

Now try to press one of the Task and see how your HS100 smart plug responds!

I love WearTasker. I find it extremely usefull to be able to call Tasker tasks from my watch. Some other tasks I have there are one to power off my home server, one to refresh my Plex library, and one to send a Whatsapp to my wife with my current location and current route ETA.

]]>
http://itnerd.space/2017/04/03/control-your-tp-link-hs100-smart-plug-from-your-android-watch/feed/ 0 254
How to remotely get the state of your HS100 smart plug http://itnerd.space/2017/01/29/get-the-state-of-your-hs100-smart-plug/ http://itnerd.space/2017/01/29/get-the-state-of-your-hs100-smart-plug/#comments Sun, 29 Jan 2017 18:29:49 +0000 http://itnerd.space/?p=223 In previous posts we’ve seen how to remotely switch On/Off our TP-Link HS100 smart plug, and how to control it with IFTTT. In this post we’ll see how we can remotely obtain the state of the HS100 relay: On or Off, from command line. I even do it with Tasker for Android!

Please be sure to refer to this post if you are unsure how to obtain the Token and DeviceID that are necessary to control the plug via TP-Link cloud service.

TL;DR: The one-liner below, run in a Linux/Android/Mac shell, will return ON or OFF, indicating what is the state of an HS100 relay:

curl -s --request POST "https://wap.tplinkcloud.com/?token=TOKEN_HERE HTTP/1.1"\
 --data '{"method":"passthrough", "params": {"deviceId": "DEVICEID_HERE", "requestData": "{\"system\":{\"get_sysinfo\":null},\"emeter\":{\"get_realtime\":null}}" }}'\
 --header "Content-Type: application/json" | grep -q '..relay_state..:1' && echo "ON" || echo "OFF"

I’ve put this line above in a Tasker shell action, and I can perfectly obtain my HS100 state from Tasker now! So cool.

For the one wondering what we can obtain with the get_sysinfo command: run the following line. Here I extract from the Json output the responseData field, which contains the interesting payload, I unescape it with sed, and pretty-format it using json_pp:

curl -s --request POST "https://wap.tplinkcloud.com/?token=TOKEN_HERE HTTP/1.1"\
  --data '{"method":"passthrough", "params": {"deviceId": "DEVICEID_HERE", "requestData": "{\"system\":{\"get_sysinfo\":null},\"emeter\":{\"get_realtime\":null}}" }}'\
  --header "Content-Type: application/json" | jq ".result.responseData" | sed -e 's#\\\"#"#g; s#^\"##; s#\"$##' | json_pp

The output would be something like this. I’ve masked most of the data for obvious privacy reasons, but you can still get the idea. We see the position, time the device was On, MAC Address, Model, Alias (custom name)…

{
 "system" : {
 "get_sysinfo" : {
 "fwId" : "FWID_HERE",
 "relay_state" : 1,
 "dev_name" : "Wi-Fi Smart Plug",
 "oemId" : "OEMID_HERE",
 "on_time" : 451,
 "model" : "HS100(EU)",
 "icon_hash" : "",
 "updating" : 0,
 "led_off" : 0,
 "err_code" : 0,
 "longitude" : LONGITUDE_HERE,
 "mac" : "MAC_ADD_HERE",
 "hwId" : "HWID_HERE",
 "rssi" : -53,
 "deviceId" : "DEVICEID_HERE",
 "latitude" : LATITUDE_HERE,
 "sw_ver" : "1.0.8 Build 151101 Rel.24452",
 "alias" : "My Smart Plug",
 "type" : "smartplug",
 "hw_ver" : "1.0",
 "feature" : "TIM",
 "active_mode" : "schedule"
 }
 },
 "emeter" : {
 "err_msg" : "module not support",
 "err_code" : -1
 }
}

I guess an HS110 which has some energy consumption colection capability would give more data in the emeter section. Mine is an HS100, and I get “module not support(ed)”. Don’t hesitate to send me some example of an HS110 output energy data, I’ll put them here as well.

We can also extract one particular field’s value using a one-liner like the one below. Here I would extract the value of the relay_state field:

curl -s --request POST "https://wap.tplinkcloud.com/?token=TOKEN_HERE HTTP/1.1"\
 --data '{"method":"passthrough", "params": {"deviceId": "DEVICEID_HERE", "requestData": "{\"system\":{\"get_sysinfo\":null},\"emeter\":{\"get_realtime\":null}}" }}'\
 --header "Content-Type: application/json" | jq ".result.responseData" | sed -e 's#\\\"#"#g; s#^\"##; s#\"$##' | jq ".system.get_sysinfo.relay_state"
]]>
http://itnerd.space/2017/01/29/get-the-state-of-your-hs100-smart-plug/feed/ 7 223
Control your TP-Link HS100 smart plug with IFTTT http://itnerd.space/2017/01/22/control-your-tp-link-hs100-smart-plug-with-ifttt/ http://itnerd.space/2017/01/22/control-your-tp-link-hs100-smart-plug-with-ifttt/#comments Sun, 22 Jan 2017 16:32:43 +0000 http://itnerd.space/?p=208 In my previous post we saw how we can control a TP-Link HS100 smart plug from command line from anywhere on Internet, without the Kasa app. In this post we’ll see how to switch the plug On/Off directly from IFTTT, without any third-party component, nor without any other device at home other than the smart plug itself.

In IFTTT we’ll use the Maker service, which let’s us call a custom HTTP GET/POST request with some Json payload, so that’s exactly what we need here.

Note: If you haven’t already, follow the steps in my previous post, to figure out what your Token and Device ID are.

Then create a new Recipe Applet like you normally would in IFTTT, and choose the “Maker Webhook / Make a Web Request” action service to define a new action.

For the URL, I’ve used:

https://eu-wap.tplinkcloud.com/?token=YOUR_TOKEN_HERE

and the method type is POST.

Note: For the URL: please read this other post, as you might need to use a different URL depending the region where you are from.


The Content Type is application/json, and the payload to switch the plug On should be:

{"method":"passthrough",
"params": {"deviceId": "YOUR_DEVICEID_HERE",
"requestData": "{\"system\":{\"set_relay_state\":{\"state\":1}
}
}" }
}

If you want to switch the plug Off, just replace the state 1 with state 0.

Notice how I have added extra carriage returns to separate the “}” at the end, otherwise IFTTT was giving me some error.

That’s it! Easy, right?

]]>
http://itnerd.space/2017/01/22/control-your-tp-link-hs100-smart-plug-with-ifttt/feed/ 38 208
How to control your TP-Link HS100 smartplug from Internet http://itnerd.space/2017/01/22/how-to-control-your-tp-link-hs100-smartplug-from-internet/ http://itnerd.space/2017/01/22/how-to-control-your-tp-link-hs100-smartplug-from-internet/#comments Sun, 22 Jan 2017 14:04:59 +0000 http://itnerd.space/?p=190 I recently acquired a TP-Link HS100 smart plug. Once you install and register the plug and the companion app (Kasa), you’ll be able to do some cool things like turn on/off the plug from your smartphone, schedule on/off at some time. You can also put the plug in Away Mode, so that the plug will randomly turn on/off in the specified time/date interval.

Kasa for Mobile (Free, Google Play) →

These are already really cool features, but I wanted to be able to do more with it: for example, turn on the plug when I arrive home, and turn it off 5min after I leave home. This is of course out of the scope of the Kasa app features, but I was more thinking about being able to control the plug from a smartphone automation App like Tasker, or a cloud service like IFTTT.

While there are some resources available explaining how to control the TP-Link HS100 plug from another device connected to the same Wifi network, I haven’t been able to find any that would explain how to do it via the TP-Link web service, so this is what I’ll show here.

In this post I’ll show how to change the relay state of the plug via command line from any device connected to Internet, not only from the local Wifi, which can then be called from a script, or from Tasker on Android.

Arquitecture

There are basically 3 components involved here:

  • A web service from TP-Link
  • The Kasa app that runs on your Smartphone, connected to Internet (via your Wifi network, or any network for that matter). It does (at least) two things:
    • Periodically get the status of the plug (is it turned on/off), and show the status in teh app (green icon if the plug is switched on). This happens every two seconds, when the app is in foreground and visible.
    • When the user toggles the switch from the app, it will send the new relay state change request to the TP-Link web service.
  • The plug, connected to Internet via your wifi network: It will periodically contact the TP-Link web service for any status change, like a request to turn on/off.

Communication overview

This is how the Kasa app communicates itself with the TP-Link web service. In this case when the user switches the plug On, the app will send an HTTP POST request (over SSL) like this one:

POST https://eu-wap.tplinkcloud.com/?token=74adcc7e-64f7-47c1-a751-dece6d2f4704&appName=Kasa_Android&termID=c69d10e5-5307-4602-b2c8-eee8f3761238&appVer=1.4.4.607&ospf=Android+6.0.1&netType=wifi&locale=en_US HTTP/1.1
Content-Type: application/json
User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; XXPhoneModelXX)
Connection: Keep-Alive
Content-Length: 160
Host: eu-wap.tplinkcloud.com

{
 "method":"passthrough",
 "params":{
 "deviceId":"80067AC4FDBD41C54C55896BFA28EAD38A87A5A4",
 "requestData":"{\"system\":{\"set_relay_state\":{\"state\":1}}}"
 }
}

To which the TP-Link server will respond (when successful):

{
 "error_code":0,
 "result":{
 "responseData":"{\"system\":{\"set_relay_state\":{\"err_code\":0}}}"
 }
}

As expected, almost instantly, the plug will switch On.

I have highlighted 4 fields/values in the request above. This values are specific to you and your plug. This is how the TP-Link web service identifies you and which of your plugs you want to switch.

  • Token (token=74adcc7e-64f7-47c1-a751-dece6d2f4704): passed in the URL, this is acting as a authentication. The Kasa app obtains it from the TP-Link server when you log in to the service via the App. The user and passwords are not used anymore after that. All communications use the token.
  • DeviceID (“deviceId”:”80067AC4FDBD41C54C55896BFA28EAD38A87A5A4″): passed in the Json payload, it references the device we wan’t to control.
  • TermID (termID=c69d10e5-5307-4602-b2c8-eee8f3761238): ID of the Client (the Kasa app installed in that particular phone). This doesn’t seem to be a compulsory field.
  • state: this is the desired state we want to put the relay into. 1 for On, 0 for Off.

Note: I have changed all the values shown above, to avoid having anyone control my plug by error. I have also formated the Json payloads.

Knowing that, we can now reproduce the same requests, for example using curl, from the command line (even in a Tasker task!). The TP-Link server will have aboslutely no way of telling of the request was originating from the Kasa app or a script.

Now, let see how we can call again the same request from a linux command line using curl. I have removed some parameters, like the User-Agent, and some others in the URL query string, and it still works, so I assume they eventually use them for statistical reasons only:

curl --request POST "https://eu-wap.tplinkcloud.com/?token=74adcc7e-64f7-47c1-a751-dece6d2f4704 HTTP/1.1" \
 --data '{"method":"passthrough", "params": {"deviceId": "80067AC4FDBD41C54C55896BFA28EAD38A87A5A4", "requestData": "{\"system\":{\"set_relay_state\":{\"state\":1}}}" }}' \
--header "Content-Type: application/json"

Of course, we need a way to identify the value of this fields. That’s what I’ll cover below.

Data extraction

UPDATE (06/20/2017): this “Data extraction” part is now obsolete. I leave it here for historical purpose. Instead you can now follow the following steps:

  1. Authenticate to TP-Link cloud API and get a token
  2. Get the end point URL and Device ID

OBSOLETE CONTENT STARTS HERE

This is what we’ll need:

  1. Android phone with Kasa app installed and already registred, with the plug added to the app
  2. Computer with some tools to unpack the Android Backup file (adb, python, sqlite3,…)
  3. Phone with adb enabled

First let’s take an Android Backup of the Kasa app:

adb backup -f backup.ab com.tplink.kasa_android

Now let’s unpack the backup with this one-liner:

dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -

Now we just need to find the relevant information. I show you how to retrieve the values for each field:

  • Token
$ sqlite3 db/iot.1.db "select token from accounts;"
74adcc7e-64f7-47c1-a751-dece6d2f4704
  • deviceID
$ sqlite3 db/iot.1.db "select deviceAlias,deviceID from devices;"My Smart Plug|80067AC4FDBD41C54C55896BFA28EAD38A87A5A4
  • termId
$ cat f/INSTALLATION
c69d10e5-5307-4602-b2c8-eee8f3761238

For people on Windows, some users reported in the comments below that you can use Android Backup Extractor (ABE) to extract the backup, instead of dd. See these links:

OBSOLETE CONTENT ENDS HERE

Now, control the plug without the Kasa App

If you follow these steps above you can extract the token and device ID corresponding to your Kasa app and smartplug. You can now control the smart plug from anywhere, without the need to use the Kasa app. For example, you can use the curl expression below, after you replace the values with yours:

  • Turn On the plug:
curl --request POST "https://eu-wap.tplinkcloud.com/?token=YOUR_TOKEN_HERE HTTP/1.1" \
  --data '{"method":"passthrough", "params": {"deviceId": "YOUR_DEVICEID_HERE", "requestData": "{\"system\":{\"set_relay_state\":{\"state\":1}}}" }}' \
  --header "Content-Type: application/json"
  • Turn Off the plug:
curl --request POST "https://eu-wap.tplinkcloud.com/?token=YOUR_TOKEN_HERE HTTP/1.1" \
 --data '{"method":"passthrough", "params": {"deviceId": "YOUR_DEVICEID_HERE", "requestData": "{\"system\":{\"set_relay_state\":{\"state\":0}}}" }}' \
 --header "Content-Type: application/json"

Common issues

  • AppServerURL: You’ll need to change the URL used to control the plug with the correct one specific for your plug: See how to find it here.
  • [obsolete]{“error_code”:-20580,”msg”:”Account is not binded to the device“}: Some have reported issues with the URL eu-wap.tplinkcloud.com used in this tutorial. Here are all the known (to me) URLs of different TP-Link backend instances. If you have some problem like the previous error, try a different URL:
    • use1-wap.tplinkcloud.com if you are near the US region
    • aps1-wap.tplinkcloud.com if you are near the Asia Pacific region
    • eu-wap.tplinkcloud.com if you are near the Europe region
    • wap.tplinkcloud.com, without any region prefix[/obsolete]
  • If you get an expired or invalid token error, logout from Kasa app, then login again with your account and extract again the token from the app. Some have needed to uninstall the app completely, reinstall it and start over.
  • Be sure to enable Remote Control of the plug. You will find the option in the Kasa App, enter the Plug, then there’s a Plug settings button. There enable Remote control.

If you have any questions or comment, please, do not hesitate to let me know, using the comments below :).

In future posts I’ll show how to integrate your HS100 smart plug with the cloud Automation service IFTTT (see here), and how to control it from the Android Automation app Tasker or your Smartwatch, as well as how to get the state (On/Off) of the plug.

]]>
http://itnerd.space/2017/01/22/how-to-control-your-tp-link-hs100-smartplug-from-internet/feed/ 129 190