Skip to content

Instantly share code, notes, and snippets.

@jacoby
Created February 7, 2013 17:38
Show Gist options
  • Save jacoby/4732649 to your computer and use it in GitHub Desktop.
Save jacoby/4732649 to your computer and use it in GitHub Desktop.
Simple program to read battery information and last synchronization from my FitBit device. Amongst the bugs: Only reads one device, hardcoded consumer key and secret. But an early working piece of Python code, adapted from https://groups.google.com/forum/#!msg/fitbit-api/CkXQ6-0-vMs/VaX_V6gm3BUJ.
#!/usr/bin/env python
'''
Description:
Using the FitBit API get the device info
then, put it into the Redis NoSQL database for other programs to check
Displays:
<?xml version="1.0" encoding="UTF-8"?><result><summary><activeScore>44</activeScore><caloriesOut>1894</caloriesOut><distances><activityDistance><activity>total</activity><distance>0.11</distance></activityDistance><activityDistance><activity>tracker</activity><distance>0.11</distance></activityDistance><activityDistance><activity>loggedActivities</activity><distance>0</distance></activityDistance><activityDistance><activity>veryActive</activity><distance>0</distance></activityDistance><activityDistance><activity>moderatelyActive</activity><distance>0.03</distance></activityDistance><activityDistance><activity>lightlyActive</activity><distance>0.08</distance></activityDistance><activityDistance><activity>sedentaryActive</activity><distance>0</distance></activityDistance></distances><fairlyActiveMinutes>7</fairlyActiveMinutes><lightlyActiveMinutes>20</lightlyActiveMinutes><sedentaryMinutes>1413</sedentaryMinutes><steps>260</steps><veryActiveMinutes>0</veryActiveMinutes></summary></result>
Reference:
http://wiki.fitbit.com/display/API/Fitbit+API
http://wiki.fitbit.com/display/API/API-Get-Activities
http://wiki.fitbit.com/display/API/OAuth-Authentication-API#OAuth-Authentication-API-TheOAuthFlow
http://oauth.net/core/1.0a/
Notes:
FitBit API rejects oauth.OAuthSignatureMethod_HMAC_SHA1()
generated signatures so use oauth.OAuthSignatureMethod_PLAINTEXT()
instead.
'''
import os, httplib
import datetime
import redis
import simplejson as json
import time
# Install oauth for python. On Ubuntu run: sudo apt-get install python-oauth
from oauth import oauth
#XXX: register your FitBit client: https://dev.fitbit.com/apps/new
#XXX: which gives you a consumer key/secret
CONSUMER_KEY = '#####YOUDONTGETTOHAVEMYKEYS#####'
CONSUMER_SECRET = '#YOUDONTGETTOHAVEMYSECRETSEITHER'
SERVER = 'api.fitbit.com'
REQUEST_TOKEN_URL = 'http://%s/oauth/request_token' % SERVER
ACCESS_TOKEN_URL = 'http://%s/oauth/access_token' % SERVER
AUTHORIZATION_URL = 'http://%s/oauth/authorize' % SERVER
ACCESS_TOKEN_STRING_FNAME = '/home/jacoby/dev/FitBit/access_token.string'
DEBUG = False
# pass oauth request to server (use httplib.connection passed in as param)
# return response as a string
def fetch_response(oauth_request, connection, debug=DEBUG):
url= oauth_request.to_url()
connection.request(oauth_request.http_method,url)
response = connection.getresponse()
s=response.read()
if debug:
print 'requested URL: %s' % url
print 'server response: %s' % s
return s
def main():
connection = httplib.HTTPSConnection(SERVER)
consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET)
# XXX: hmac-sha1 does not work; use plain text
#signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
signature_method = oauth.OAuthSignatureMethod_PLAINTEXT()
# if we don't have a cached access-token stored in a file, then get one
if not os.path.exists(ACCESS_TOKEN_STRING_FNAME):
print '* Obtain a request token ...'
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
consumer, http_url=REQUEST_TOKEN_URL)
if DEBUG:
connection.set_debuglevel(10)
oauth_request.sign_request(signature_method, consumer, None)
resp=fetch_response(oauth_request, connection)
auth_token=oauth.OAuthToken.from_string(resp)
print 'Auth key: %s' % str(auth_token.key)
print 'Auth secret: %s' % str(auth_token.secret)
print '-'*75,'\n\n'
# authorize the request token
print '* Authorize the request token ...'
auth_url="%s?oauth_token=%s" % (AUTHORIZATION_URL, auth_token.key)
print 'Authorization URL:\n%s' % auth_url
oauth_verifier = raw_input(
'Please go to the above URL and authorize the '+
'app -- Type in the Verification code from the website, when done: ')
print '* Obtain an access token ...'
# note that the token we're passing to the new
# OAuthRequest is our current request token
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
consumer, token=auth_token, http_url=ACCESS_TOKEN_URL,
parameters={'oauth_verifier': oauth_verifier})
oauth_request.sign_request(signature_method, consumer, auth_token)
# now the token we get back is an access token
# parse the response into an OAuthToken object
access_token=oauth.OAuthToken.from_string(
fetch_response(oauth_request,connection))
print 'Access key: %s' % str(access_token.key)
print 'Access secret: %s' % str(access_token.secret)
print '-'*75,'\n\n'
# write the access token to file; next time we just read it from file
if DEBUG:
print 'Writing file', ACCESS_TOKEN_STRING_FNAME
fobj = open(ACCESS_TOKEN_STRING_FNAME, 'w')
access_token_string = access_token.to_string()
fobj.write(access_token_string)
fobj.close()
else:
if DEBUG:
print 'Reading file', ACCESS_TOKEN_STRING_FNAME
fobj = open(ACCESS_TOKEN_STRING_FNAME)
access_token_string = fobj.read()
fobj.close()
access_token = oauth.OAuthToken.from_string(access_token_string)
apiCall = '/1/user/-/devices.json'
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
consumer,
token=access_token,
http_url=apiCall
)
oauth_request.sign_request(signature_method, consumer, access_token)
headers = oauth_request.to_header(realm='api.fitbit.com')
connection.request('GET', apiCall, headers=headers)
resp = connection.getresponse()
device_info = resp.read()
devices = json.loads( device_info )
device = devices[0]
device_id = 'fitbit%' + device['id']
rs = redis.Redis()
rs.hset( device_id , 'battery' , device['battery'] )
rs.hset( device_id , 'lastSync' , device['lastSyncTime'] )
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment