Combining QuantifiedSelf with IoT for effective motivation

This post is about combining QS (a Fitbit activity tracker), with IoT (using activity information retrieved online to control a Belkin Wemo switch) for effective motivation.

Let me explain briefly how and why:

I got this Fitbit tracker mostly out of curiosity for it as a gadget, and for experimenting with the Fitbit API. Initially I have been using it quite often – and that made me walk more and climb up more stairs than usual, to meet my daily goals and earn some badges – but quickly I got bored of it and started neglecting its usage and became less active.

So then I thought, badges earning is not working for me,  there must be a way to force myself to become more active. There are great platforms for motivating people to keep healthy and exercise more, but obviously in my case I needed something more drastic. At the same time I had been playing with a Belkin Wemo switch and have found a way (using some good online resources) to control it outside the iOS app. 

And this is how I came up with the idea of ‘punishing’ myself when I am not active enough by turning off automatically the switch that powers something important. I don’t watch TV, and I thought first of the DSL router but then there would be no connection to the Wemo to turn it back on. So I thought of connecting the fridge to the Wemo switch.

All I needed then was a service to monitor my Fitbit account and my activity that would also turn on/off the switch. For this I built a webscript that checks my daily activity through the Fitbit API. Every evening it will check for the total steps tracked by the Fitbit device. If my activity is below some threshold it gives me a warning email first. Then it checks again within 1 hour and if the threshold is still not met it shuts down the Wemo. It will recheck every 1 hour then and will turn on the switch in case I have made enough steps!

I have used webscript.io because Lua is very simple and webscript guys have done great work integrating libraries that simplify oauth authentication and communication over HTTP. Regarding the communication with the Wemo switch there are two options. Basically, the Wemo talks uPnP (though the service XML is not properly formatted and therefore no uPnP app is able to detect it within your network), so all it takes it to make a POST request to the Wemo IP and port 49153 sending the appropriate XML service file as part of the request data.

Update: This is how actually a direct request to Wemo switch looks like (in Lua code):

function controlWemo(status, port)
local response = http.request {
url = 'http://192.168.1.1:49153/upnp/control/basicevent1',
method = 'POST',
headers = {
charset='utf-8',
SOAPACTION = '"urn:Belkin:service:basicevent:1#SetBinaryState"'
},
data = '<!--?xml version="1.0" encoding="utf-8"?-->'..status..''
}

return response
end

One option is to send a request directly to the switch using dyndns and port forwarding at the home router or (more preferably for me) use a Pub/Sub service like Pusher and a device at the local network (like a powerplug, a beagleboard or a RaspberryPi) that listens for events from Pusher and sends the command to the Wemo switch.

The network communication looks like the following:

To read data using the Fitbit API, user must authorise the web application (webscript in this case). The API is based on OAuth for authenticating external applications and the webscript url must be also registered as a Fitbit application. When registering your Fitbit application, you receive an app token and secret (to be used in your code). More information about the Fitbit API can be found here.

Based on the Twitter sample webscript that demonstrates usage of Oauth, I have created 2 scripts. The first one directs to the Fitbit site for granting access to the second script that retrieves my activity data and talks to Wemo switch. The code for the first one is the following:


local CONSUMERTOKEN = '39-------------0e' --your apps Fitbit token
local CONSUMERSECRET = 'bf6b---------------3cb' --your apps Fitbit secrer

-- get a request token
local response = http.request {
url = 'http://api.fitbit.com/oauth/request_token',
params = { oauth_callback =
'http://fitbit.webscript.io/callback' },
auth = { oauth = {
consumertoken = CONSUMERTOKEN,
consumersecret = CONSUMERSECRET
}}
}

local ret = http.qsparse(response.content)

-- store the token's secret for use in the callback
storage['secret:'..ret.oauth_token] = ret.oauth_token_secret

-- redirect the user to login at Fitbit
return 302, '', {
Location=
'http://api.fitbit.com/oauth/authorize?oauth_token='
..ret.oauth_token
}

The second webscript is the callback to the previous one (to my example http://fitbit.webscript.io/callback) which is the endpoint you have registered to Fitbit as the URL the user is redirected to when successfully authorised the webscript. The code for both scripts can be found here.

This is what I consider a true IoT example. It involves two different devices from different vendors, exchanging information and acting smartly (well not very smartly but it’s a start) for my benefit.

9 Comments

  1. tamberg February 3, 2013 2:30 pm Reply

    Great IoT mashup! Kind regards, Thomas

    http://twitter.com/tamberg

    • Charalampos February 6, 2013 7:52 am Reply

      Thanks Thomas! :-)

  2. Issac Kelly February 5, 2013 5:07 am Reply

    Hey thanks for the link, glad you liked my work! I stumbled on this on Hackaday, funny it hit several of my interests (I wrote a python fitbit lib for a client last year) Cheers!

    http://www.issackelly.com

    • Charalampos February 5, 2013 12:57 pm Reply

      Thanks for providing such great information on how Wemo works! :-)

  3. Catherine April 15, 2013 3:05 pm Reply

    I am writing a business story about FitBit including a section on how people are hacking this device. I’d love to talk to you — please contact me on email. Thanks!

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>